Mono changes:
[mono.git] / mcs / class / Mono.Data.Sqlite / Mono.Data.Sqlite_2.0 / SQLiteParameterCollection.cs
1 /********************************************************\r
2  * ADO.NET 2.0 Data Provider for SQLite Version 3.X\r
3  * Written by Robert Simpson (robert@blackcastlesoft.com)\r
4  * \r
5  * Released to the public domain, use at your own risk!\r
6  ********************************************************/\r
7 \r
8 namespace Mono.Data.Sqlite\r
9 {\r
10   using System;\r
11   using System.Data;\r
12   using System.Data.Common;\r
13   using System.Collections.Generic;\r
14   using System.Globalization;\r
15   using System.ComponentModel;\r
16   using System.Reflection;\r
17 \r
18   /// <summary>\r
19   /// SQLite implementation of DbParameterCollection.\r
20   /// </summary>\r
21 #if !PLATFORM_COMPACTFRAMEWORK\r
22   [Editor("Microsoft.VSDesigner.Data.Design.DBParametersEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), ListBindable(false)]\r
23 #endif\r
24   public sealed class SqliteParameterCollection : DbParameterCollection\r
25   {\r
26     /// <summary>\r
27     /// The underlying command to which this collection belongs\r
28     /// </summary>\r
29     private SqliteCommand         _command;\r
30     /// <summary>\r
31     /// The internal array of parameters in this collection\r
32     /// </summary>\r
33     private List<SqliteParameter> _parameterList;\r
34     /// <summary>\r
35     /// Determines whether or not all parameters have been bound to their statement(s)\r
36     /// </summary>\r
37     private bool                  _unboundFlag;\r
38 \r
39     /// <summary>\r
40     /// Initializes the collection\r
41     /// </summary>\r
42     /// <param name="cmd">The command to which the collection belongs</param>\r
43     internal SqliteParameterCollection(SqliteCommand cmd)\r
44     {\r
45       _command = cmd;\r
46       _parameterList = new List<SqliteParameter>();\r
47       _unboundFlag = true;\r
48     }\r
49 \r
50     /// <summary>\r
51     /// Returns true\r
52     /// </summary>\r
53     public override bool IsSynchronized\r
54     {\r
55       get { return true; }\r
56     }\r
57 \r
58     /// <summary>\r
59     /// Returns false\r
60     /// </summary>\r
61     public override bool IsFixedSize\r
62     {\r
63       get { return false; }\r
64     }\r
65 \r
66     /// <summary>\r
67     /// Returns false\r
68     /// </summary>\r
69     public override bool IsReadOnly\r
70     {\r
71       get { return false; }\r
72     }\r
73 \r
74     /// <summary>\r
75     /// Returns null\r
76     /// </summary>\r
77     public override object SyncRoot\r
78     {\r
79       get { return null; }\r
80     }\r
81 \r
82     /// <summary>\r
83     /// Retrieves an enumerator for the collection\r
84     /// </summary>\r
85     /// <returns>An enumerator for the underlying array</returns>\r
86     public override System.Collections.IEnumerator GetEnumerator()\r
87     {\r
88       return _parameterList.GetEnumerator();\r
89     }\r
90 \r
91     /// <summary>\r
92     /// Adds a parameter to the collection\r
93     /// </summary>\r
94     /// <param name="parameterName">The parameter name</param>\r
95     /// <param name="parameterType">The data type</param>\r
96     /// <param name="parameterSize">The size of the value</param>\r
97     /// <param name="sourceColumn">The source column</param>\r
98     /// <returns>A SqliteParameter object</returns>\r
99     public SqliteParameter Add(string parameterName, DbType parameterType, int parameterSize, string sourceColumn)\r
100     {\r
101       SqliteParameter param = new SqliteParameter(parameterName, parameterType, parameterSize, sourceColumn);\r
102       Add(param);\r
103 \r
104       return param;\r
105     }\r
106 \r
107     /// <summary>\r
108     /// Adds a parameter to the collection\r
109     /// </summary>\r
110     /// <param name="parameterName">The parameter name</param>\r
111     /// <param name="parameterType">The data type</param>\r
112     /// <param name="parameterSize">The size of the value</param>\r
113     /// <returns>A SqliteParameter object</returns>\r
114     public SqliteParameter Add(string parameterName, DbType parameterType, int parameterSize)\r
115     {\r
116       SqliteParameter param = new SqliteParameter(parameterName, parameterType, parameterSize);\r
117       Add(param);\r
118 \r
119       return param;\r
120     }\r
121 \r
122     /// <summary>\r
123     /// Adds a parameter to the collection\r
124     /// </summary>\r
125     /// <param name="parameterName">The parameter name</param>\r
126     /// <param name="parameterType">The data type</param>\r
127     /// <returns>A SqliteParameter object</returns>\r
128     public SqliteParameter Add(string parameterName, DbType parameterType)\r
129     {\r
130       SqliteParameter param = new SqliteParameter(parameterName, parameterType);\r
131       Add(param);\r
132 \r
133       return param;\r
134     }\r
135 \r
136     /// <summary>\r
137     /// Adds a parameter to the collection\r
138     /// </summary>\r
139     /// <param name="parameter">The parameter to add</param>\r
140     /// <returns>A zero-based index of where the parameter is located in the array</returns>\r
141     public int Add(SqliteParameter parameter)\r
142     {\r
143       int n = -1;\r
144 \r
145       if (String.IsNullOrEmpty(parameter.ParameterName) == false)\r
146       {\r
147         n = IndexOf(parameter.ParameterName);\r
148       }\r
149 \r
150       if (n == -1)\r
151       {\r
152         n = _parameterList.Count;\r
153         _parameterList.Add((SqliteParameter)parameter);\r
154       }\r
155 \r
156       SetParameter(n, parameter);\r
157 \r
158       return n;\r
159     }\r
160 \r
161     /// <summary>\r
162     /// Adds a parameter to the collection\r
163     /// </summary>\r
164     /// <param name="value">The parameter to add</param>\r
165     /// <returns>A zero-based index of where the parameter is located in the array</returns>\r
166 #if !PLATFORM_COMPACTFRAMEWORK\r
167     [EditorBrowsable(EditorBrowsableState.Never)]\r
168 #endif\r
169     public override int Add(object value)\r
170     {\r
171       return Add((SqliteParameter)value);\r
172     }\r
173 \r
174     /// <summary>\r
175     /// Adds a named/unnamed parameter and its value to the parameter collection.\r
176     /// </summary>\r
177     /// <param name="parameterName">Name of the parameter, or null to indicate an unnamed parameter</param>\r
178     /// <param name="value">The initial value of the parameter</param>\r
179     /// <returns>Returns the SqliteParameter object created during the call.</returns>\r
180     public SqliteParameter AddWithValue(string parameterName, object value)\r
181     {\r
182       SqliteParameter param = new SqliteParameter(parameterName, value);\r
183       Add(param);\r
184 \r
185       return param;\r
186     }\r
187 \r
188     /// <summary>\r
189     /// Adds an array of parameters to the collection\r
190     /// </summary>\r
191     /// <param name="values">The array of parameters to add</param>\r
192     public void AddRange(SqliteParameter[] values)\r
193     {\r
194       int x = values.Length;\r
195       for (int n = 0; n < x; n++)\r
196         Add(values[n]);\r
197     }\r
198 \r
199     /// <summary>\r
200     /// Adds an array of parameters to the collection\r
201     /// </summary>\r
202     /// <param name="values">The array of parameters to add</param>\r
203     public override void AddRange(Array values)\r
204     {\r
205       int x = values.Length;\r
206       for (int n = 0; n < x; n++)\r
207         Add((SqliteParameter)(values.GetValue(n)));\r
208     }\r
209 \r
210     /// <summary>\r
211     /// Clears the array and resets the collection\r
212     /// </summary>\r
213     public override void Clear()\r
214     {\r
215       _unboundFlag = true;\r
216       _parameterList.Clear();\r
217     }\r
218 \r
219     /// <summary>\r
220     /// Determines if the named parameter exists in the collection\r
221     /// </summary>\r
222     /// <param name="parameterName">The name of the parameter to check</param>\r
223     /// <returns>True if the parameter is in the collection</returns>\r
224     public override bool Contains(string parameterName)\r
225     {\r
226       return (IndexOf(parameterName) != -1);\r
227     }\r
228 \r
229     /// <summary>\r
230     /// Determines if the parameter exists in the collection\r
231     /// </summary>\r
232     /// <param name="value">The SqliteParameter to check</param>\r
233     /// <returns>True if the parameter is in the collection</returns>\r
234     public override bool Contains(object value)\r
235     {\r
236       return _parameterList.Contains((SqliteParameter)value);\r
237     }\r
238 \r
239     /// <summary>\r
240     /// Not implemented\r
241     /// </summary>\r
242     /// <param name="array"></param>\r
243     /// <param name="index"></param>\r
244     public override void CopyTo(Array array, int index)\r
245     {\r
246       throw new NotImplementedException();\r
247     }\r
248 \r
249     /// <summary>\r
250     /// Returns a count of parameters in the collection\r
251     /// </summary>\r
252     public override int Count\r
253     {\r
254       get { return _parameterList.Count; }\r
255     }\r
256 \r
257     /// <summary>\r
258     /// Overloaded to specialize the return value of the default indexer\r
259     /// </summary>\r
260     /// <param name="parameterName">Name of the parameter to get/set</param>\r
261     /// <returns>The specified named SQLite parameter</returns>\r
262     public new SqliteParameter this[string parameterName]\r
263     {\r
264       get\r
265       {\r
266         return (SqliteParameter)GetParameter(parameterName);\r
267       }\r
268       set\r
269       {\r
270         SetParameter(parameterName, value);\r
271       }\r
272     }\r
273 \r
274     /// <summary>\r
275     /// Overloaded to specialize the return value of the default indexer\r
276     /// </summary>\r
277     /// <param name="index">The index of the parameter to get/set</param>\r
278     /// <returns>The specified SQLite parameter</returns>\r
279     public new SqliteParameter this[int index]\r
280     {\r
281       get\r
282       {\r
283         return (SqliteParameter)GetParameter(index);\r
284       }\r
285       set\r
286       {\r
287         SetParameter(index, value);\r
288       }\r
289     }\r
290     /// <summary>\r
291     /// Retrieve a parameter by name from the collection\r
292     /// </summary>\r
293     /// <param name="parameterName">The name of the parameter to fetch</param>\r
294     /// <returns>A DbParameter object</returns>\r
295     protected override DbParameter GetParameter(string parameterName)\r
296     {\r
297       return GetParameter(IndexOf(parameterName));\r
298     }\r
299 \r
300     /// <summary>\r
301     /// Retrieves a parameter by its index in the collection\r
302     /// </summary>\r
303     /// <param name="index">The index of the parameter to retrieve</param>\r
304     /// <returns>A DbParameter object</returns>\r
305     protected override DbParameter GetParameter(int index)\r
306     {\r
307       return _parameterList[index];\r
308     }\r
309 \r
310     /// <summary>\r
311     /// Returns the index of a parameter given its name\r
312     /// </summary>\r
313     /// <param name="parameterName">The name of the parameter to find</param>\r
314     /// <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>\r
315     public override int IndexOf(string parameterName)\r
316     {\r
317       int x = _parameterList.Count;\r
318       for (int n = 0; n < x; n++)\r
319       {\r
320         if (String.Compare(parameterName, _parameterList[n].ParameterName, true, CultureInfo.InvariantCulture) == 0)\r
321           return n;\r
322       }\r
323       return -1;\r
324     }\r
325 \r
326     /// <summary>\r
327     /// Returns the index of a parameter\r
328     /// </summary>\r
329     /// <param name="value">The parameter to find</param>\r
330     /// <returns>-1 if not found, otherwise a zero-based index of the parameter</returns>\r
331     public override int IndexOf(object value)\r
332     {\r
333       return _parameterList.IndexOf((SqliteParameter)value);\r
334     }\r
335 \r
336     /// <summary>\r
337     /// Inserts a parameter into the array at the specified location\r
338     /// </summary>\r
339     /// <param name="index">The zero-based index to insert the parameter at</param>\r
340     /// <param name="value">The parameter to insert</param>\r
341     public override void Insert(int index, object value)\r
342     {\r
343       _unboundFlag = true;\r
344       _parameterList.Insert(index, (SqliteParameter)value);\r
345     }\r
346 \r
347     /// <summary>\r
348     /// Removes a parameter from the collection\r
349     /// </summary>\r
350     /// <param name="value">The parameter to remove</param>\r
351     public override void Remove(object value)\r
352     {\r
353       _unboundFlag = true;\r
354       _parameterList.Remove((SqliteParameter)value);\r
355     }\r
356 \r
357     /// <summary>\r
358     /// Removes a parameter from the collection given its name\r
359     /// </summary>\r
360     /// <param name="parameterName">The name of the parameter to remove</param>\r
361     public override void RemoveAt(string parameterName)\r
362     {\r
363       RemoveAt(IndexOf(parameterName));\r
364     }\r
365 \r
366     /// <summary>\r
367     /// Removes a parameter from the collection given its index\r
368     /// </summary>\r
369     /// <param name="index">The zero-based parameter index to remove</param>\r
370     public override void RemoveAt(int index)\r
371     {\r
372       _unboundFlag = true;\r
373       _parameterList.RemoveAt(index);\r
374     }\r
375 \r
376     /// <summary>\r
377     /// Re-assign the named parameter to a new parameter object\r
378     /// </summary>\r
379     /// <param name="parameterName">The name of the parameter to replace</param>\r
380     /// <param name="value">The new parameter</param>\r
381     protected override void SetParameter(string parameterName, DbParameter value)\r
382     {\r
383       SetParameter(IndexOf(parameterName), value);\r
384     }\r
385 \r
386     /// <summary>\r
387     /// Re-assign a parameter at the specified index\r
388     /// </summary>\r
389     /// <param name="index">The zero-based index of the parameter to replace</param>\r
390     /// <param name="value">The new parameter</param>\r
391     protected override void SetParameter(int index, DbParameter value)\r
392     {\r
393       _unboundFlag = true;\r
394       _parameterList[index] = (SqliteParameter)value;\r
395     }\r
396 \r
397     /// <summary>\r
398     /// Un-binds all parameters from their statements\r
399     /// </summary>\r
400     internal void Unbind()\r
401     {\r
402       _unboundFlag = true;\r
403     }\r
404 \r
405     /// <summary>\r
406     /// This function attempts to map all parameters in the collection to all statements in a Command.\r
407     /// Since named parameters may span multiple statements, this function makes sure all statements are bound\r
408     /// to the same named parameter.  Unnamed parameters are bound in sequence.\r
409     /// </summary>\r
410     internal void MapParameters(SqliteStatement activeStatement)\r
411     {\r
412       if (_unboundFlag == false || _parameterList.Count == 0 || _command._statementList == null) return;\r
413 \r
414       int nUnnamed = 0;\r
415       string s;\r
416       int n;\r
417       int y = -1;\r
418       SqliteStatement stmt;\r
419 \r
420       foreach(SqliteParameter p in _parameterList)\r
421       {\r
422         y ++;\r
423         s = p.ParameterName;\r
424         if (s == null)\r
425         {\r
426           s = String.Format(CultureInfo.InvariantCulture, ";{0}", nUnnamed);\r
427           nUnnamed++;\r
428         }\r
429 \r
430         int x;\r
431         bool isMapped = false;\r
432 \r
433         if (activeStatement == null)\r
434           x = _command._statementList.Count;\r
435         else\r
436           x = 1;\r
437 \r
438         stmt = activeStatement;\r
439         for (n = 0; n < x; n++)\r
440         {\r
441           isMapped = false;\r
442           if (stmt == null) stmt = _command._statementList[n];\r
443           if (stmt._paramNames != null)\r
444           {\r
445             if (stmt.MapParameter(s, p) == true)\r
446               isMapped = true;\r
447           }\r
448           stmt = null;\r
449         }\r
450 \r
451         // If the parameter has a name, but the SQL statement uses unnamed references, this can happen -- attempt to map\r
452         // the parameter by its index in the collection\r
453         if (isMapped == false)\r
454         {\r
455           s = String.Format(CultureInfo.InvariantCulture, ";{0}", y);\r
456 \r
457           stmt = activeStatement;\r
458           for (n = 0; n < x; n++)\r
459           {\r
460             if (stmt == null) stmt = _command._statementList[n];\r
461             if (stmt._paramNames != null)\r
462             {\r
463               if (stmt.MapParameter(s, p) == true)\r
464                 isMapped = true;\r
465             }\r
466             stmt = null;\r
467           }\r
468         }\r
469       }\r
470       if (activeStatement == null) _unboundFlag = false;\r
471     }\r
472   }\r
473 }\r