Merge branch 'master' of http://github.com/mono/mono
[mono.git] / mcs / class / System.Data / System.Data.ProviderBase.jvm / AbstractDbParameterCollection.cs
1 //
2 // System.Data.Common.AbstractDbParameterCollection
3 //
4 // Authors:
5 //      Konstantin Triger <kostat@mainsoft.com>
6 //      Boris Kirzner <borisk@mainsoft.com>
7 //      
8 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32
33 using System;
34 using System.Data.Common;
35 using System.Collections;
36
37 namespace System.Data.ProviderBase
38 {
39         public abstract class AbstractDbParameterCollection : DbParameterCollection
40         {
41                 #region Fields
42
43                 readonly AbstractDbCommand _parent;
44                 readonly ArrayList _list = new ArrayList();
45
46                 #endregion // Fields
47
48                 #region Constructors
49
50                 public AbstractDbParameterCollection(DbCommand parent)
51         {
52                         _parent = (AbstractDbCommand)parent;
53         }
54
55                 #endregion // Constructors
56
57                 #region Properties
58
59                 public override int Count {
60                         get { return _list.Count; }
61                 }
62
63                 public override bool IsFixedSize {
64                         get { return _list.IsFixedSize; }
65                 }
66
67                 public override bool IsReadOnly {
68                         get { return _list.IsReadOnly; }
69                 }
70
71                 public override bool IsSynchronized {
72                         get { return _list.IsSynchronized; }
73                 }
74
75                 protected abstract Type ItemType { get; }
76
77                 public override object SyncRoot {
78                         get { return _list.SyncRoot; }
79                 }
80
81                 #endregion // Properties
82
83                 #region Methods
84
85                 public override int Add (object value) {
86                         Validate (-1, value);
87                         OnSchemaChanging();
88                         ((AbstractDbParameter)value).Parent = this;
89                         return _list.Add (value);
90                 }
91
92 #if NET_2_0
93                 public override void AddRange (Array values)
94                 {
95                         foreach (object value in values)
96                                 Add (value);
97                 }
98
99 #endif
100
101                 public override void Clear () {
102                         OnSchemaChanging();
103                         if (_list != null && Count != 0) {
104                                 for (int i = 0; i < _list.Count; i++) {
105                                         ((AbstractDbParameter)_list [i]).Parent = null;
106                                 }
107                                 _list.Clear ();
108                         }
109                 }
110
111                 public override bool Contains (object value) {
112                         if (IndexOf (value) != -1)
113                                 return true;
114                         else
115                                 return false;
116                 }
117
118                 public override bool Contains (string value) {
119                         if (IndexOf (value) != -1)
120                                 return true;
121                         else
122                                 return false;
123                 }
124
125                 public override void CopyTo (Array array, int index) {
126                         _list.CopyTo (array, index);
127                 }
128
129                 public override IEnumerator GetEnumerator () {
130                         return _list.GetEnumerator ();
131                 }
132
133                 protected override DbParameter GetParameter (int index) {
134                         return (DbParameter) _list [index];
135                 }
136
137 #if NET_2_0
138                 protected override DbParameter GetParameter (string parameterName) {
139                         return GetParameter (IndexOf (parameterName));
140                 }
141
142                 protected override void SetParameter (string parameterName, DbParameter value) {
143                         SetParameter (IndexOf (parameterName), value);
144                 }
145 #endif
146
147                 public override int IndexOf (object value) {
148                         ValidateType (value);
149                         return _list.IndexOf (value);
150                 }
151
152                 public override int IndexOf (string parameterName) {
153                         if (_list == null)
154                                 return -1;
155
156                         for (int i = 0; i < _list.Count; i++) {
157                                 string name = ((DbParameter)_list [i]).ParameterName;
158                                 if (String.Compare (name, parameterName, StringComparison.OrdinalIgnoreCase) == 0) {
159                                         return i;
160                                 }
161                         }
162                         return -1;
163                 }
164
165                 public override void Insert (int index, object value) {
166                         Validate(-1, (DbParameter)value);
167                         OnSchemaChanging();
168                         ((AbstractDbParameter)value).Parent = this;
169                         _list.Insert (index, value);
170                 }
171
172                 public override void Remove (object value) {
173                         ValidateType (value);
174                         int index = IndexOf (value);
175                         RemoveIndex (index);
176                 }
177
178                 public override void RemoveAt (int index) {
179                         RemoveIndex (index);
180                 }
181
182                 public override void RemoveAt (string parameterName) {
183                         int index = IndexOf (parameterName);
184                         RemoveIndex (index);
185                 }
186
187                 protected override void SetParameter (int index, DbParameter value) {
188                         Replace (index, value);
189                 }
190
191                 void Validate (int index, object value) {
192                         ValidateType (value);
193                         AbstractDbParameter parameter = (AbstractDbParameter) value;
194
195                         if (parameter.Parent != null) {
196                                 if (parameter.Parent.Equals (this)) {
197                                         if (IndexOf (parameter) != index)
198                                                 throw ExceptionHelper.CollectionAlreadyContains (ItemType,"ParameterName",parameter.ParameterName,this);                    
199                                 }
200                                 else {
201                                         // FIXME :  The OleDbParameter with ParameterName 'MyParam2' is already contained by another OleDbParameterCollection.
202                                         throw new ArgumentException ("");
203                                 }
204                         }
205
206                         if (parameter.ParameterName == null  || parameter.ParameterName == String.Empty) {
207                                 int newIndex = 1;
208                                 string parameterName;
209                                 
210                                 do {
211                                         parameterName = "Parameter" + newIndex;
212                                         newIndex++;
213                                 }
214                                 while(IndexOf (parameterName) != -1);
215
216                                 parameter.ParameterName = parameterName;
217                         }
218                 }               
219
220                 void ValidateType (object value) {
221                         if (value == null)
222                                 throw ExceptionHelper.CollectionNoNullsAllowed (this,ItemType);
223
224                         Type objectType = value.GetType ();
225                         Type itemType = ItemType;
226
227                         if (itemType.IsInstanceOfType(objectType)) {
228                                 Type thisType = this.GetType ();
229                                 string err = String.Format ("The {0} only accepts non-null {1} type objects, not {2} objects.", thisType.Name, itemType.Name, objectType.Name);
230                                 throw new InvalidCastException (err);
231                         }
232                 }
233
234                 private void RemoveIndex (int index) {
235                         OnSchemaChanging();
236                         AbstractDbParameter oldItem = (AbstractDbParameter)_list [index];
237                         oldItem.Parent = null;
238                         _list.RemoveAt (index);
239                 }               
240
241                 private void Replace (int index, DbParameter value) {
242                         Validate (index, value);
243                         AbstractDbParameter oldItem = (AbstractDbParameter)this [index];
244                         oldItem.Parent = null;
245
246                         ((AbstractDbParameter)value).Parent = this;
247                         _list [index] = value;
248                 }
249
250                 protected internal void OnSchemaChanging()
251         {
252             if (_parent != null) {
253                 _parent.OnSchemaChanging();
254             }
255         }
256
257                 #endregion // Methods
258         }
259 }