New test.
[mono.git] / mcs / class / Mono.Data.SqliteClient / Mono.Data.SqliteClient / SqliteParameterCollection.cs
index 3e1893438caa02cfc8ab5624cb97cca5ca7bd4d9..928ee232aa1777afd150fa11533db95b8e507a3b 100644 (file)
@@ -1,10 +1,35 @@
-// -*- c-basic-offset: 8; inent-tabs-mode: nil -*-
 //
-//  SqliteParameterCollection.cs
+// Mono.Data.SqliteClient.SqliteParameterCollection.cs
 //
-//  Author(s): Vladimir Vukicevic  <vladimir@pobox.com>
+// Represents a collection of parameters relevant to a SqliteCommand as well as 
+// their respective mappings to columns in a DataSet.
 //
-//  Copyright (C) 2002  Vladimir Vukicevic
+//Author(s):           Vladimir Vukicevic  <vladimir@pobox.com>
+//                     Everaldo Canuto  <everaldo_canuto@yahoo.com.br>
+//                     Chris Turchin <chris@turchin.net>
+//                     Jeroen Zwartepoorte <jeroen@xs4all.nl>
+//                     Thomas Zoechling <thomas.zoechling@gmx.at>
+//
+// Copyright (C) 2002  Vladimir Vukicevic
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
 using System;
@@ -13,211 +38,287 @@ using System.Collections;
 
 namespace Mono.Data.SqliteClient
 {
-        public class SqliteParameterCollection : IDataParameterCollection,
-                IList
-        {
-                ArrayList numeric_param_list = new ArrayList ();
-                Hashtable named_param_hash = new Hashtable ();
-
-                public IEnumerator GetEnumerator ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void RemoveAt (string parameterName)
-                {
-                        if (!named_param_hash.Contains (parameterName))
-                                throw new ApplicationException ("Parameter " + parameterName + " not found");
-
-                        numeric_param_list.RemoveAt ((int) named_param_hash[parameterName]);
-                        named_param_hash.Remove (parameterName);
-
-                        RecreateNamedHash ();
-                }
-
-                public void RemoveAt (SqliteParameter param)
-                {
-                        RemoveAt (param.ParameterName);
-                }
-
-                public void RemoveAt (int index)
-                {
-                        RemoveAt (((SqliteParameter) numeric_param_list[index]).ParameterName);
-                }
-
-                int IList.IndexOf (object o)
-                {
-                        return IndexOf ((SqliteParameter) o);
-                }
-
-                public int IndexOf (string parameterName)
-                {
-                        return (int) named_param_hash[parameterName];
-                }
-
-                public int IndexOf (SqliteParameter param)
-                {
-                        return IndexOf (param.ParameterName);
-                }
-
-                bool IList.Contains (object value)
-                {
-                        return Contains ((SqliteParameter) value);
-                }
-
-                public bool Contains (string parameterName)
-                {
-                        return named_param_hash.Contains (parameterName);
-                }
-
-                public bool Contains (SqliteParameter param)
-                {
-                        return Contains (param.ParameterName);
-                }
-
-                object IList.this[int index] {
-                        get {
-                                return this[index];
-                        }
-                        set {
-                                CheckSqliteParam (value);
-                                this[index] = (SqliteParameter) value;
-                        }
-                }
-
-                object IDataParameterCollection.this[string parameterName] {
-                        get {
-                                return this[parameterName];
-                        }
-                        set {
-                                CheckSqliteParam (value);
-                                this[parameterName] = (SqliteParameter) value;
-                        }
-                }
-
-                public SqliteParameter this[string parameterName] {
-                        get {
-                                return this[(int) named_param_hash[parameterName]];
-                        }
-                        set {
-                                if (this.Contains (parameterName))
-                                        numeric_param_list[(int) named_param_hash[parameterName]] = value;
-                                else          // uhm, do we add it if it doesn't exist? what does ms do?
-                                        Add (value);
-                        }
-                }
-
-                public SqliteParameter this[int parameterIndex] {
-                        get {
-                                return (SqliteParameter) numeric_param_list[parameterIndex];
-                        }
-                        set {
-                                numeric_param_list[parameterIndex] = value;
-                        }
-                }
-
-                public int Add (object value)
-                {
-                        CheckSqliteParam (value);
-                        SqliteParameter sqlp = (SqliteParameter) value;
-                        if (named_param_hash.Contains (sqlp.ParameterName))
-                                throw new DuplicateNameException ("Parameter collection already contains given value.");
-
-                        named_param_hash[value] = numeric_param_list.Add (value);
-
-                        return (int) named_param_hash[value];
-                }
-
-                // IList
-
-                public SqliteParameter Add (SqliteParameter param)
-                {
-                        Add (param);
-                        return param;
-                }
-
-                public SqliteParameter Add (string name, object value)
-                {
-                        return Add (new SqliteParameter (name, value));
-                }
-
-                public SqliteParameter Add (string name, DbType type)
-                {
-                        return Add (new SqliteParameter (name, type));
-                }
-
-                public bool IsFixedSize {
-                        get {
-                                return false;
-                        }
-                }
-
-                public bool IsReadOnly {
-                        get {
-                                return false;
-                        }
-                }
-
-                public void Clear ()
-                {
-                        numeric_param_list.Clear ();
-                        named_param_hash.Clear ();
-                }
-
-                public void Insert (int index, object value)
-                {
-                        CheckSqliteParam (value);
-                        if (numeric_param_list.Count == index) {
-                                Add (value);
-                                return;
-                        }
-
-                        numeric_param_list.Insert (index, value);
-                        RecreateNamedHash ();
-                }
-
-                public void Remove (object value)
-                {
-                        CheckSqliteParam (value);
-                        RemoveAt ((SqliteParameter) value);
-                }
-
-                // ICollection
-
-                public int Count {
-                        get {
-                                return numeric_param_list.Count;
-                        }
-                }
-
-                public bool IsSynchronized {
-                        get {
-                                return false;
-                        }
-                }
-
-                public object SyncRoot {
-                        get {
-                                return null;
-                        }
-                }
-
-                public void CopyTo (Array array, int index)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                private void CheckSqliteParam (object value)
-                {
-                        if (!(value is SqliteParameter))
-                                throw new InvalidCastException ("Can only use SqliteParameter objects");
-                }
-
-                private void RecreateNamedHash ()
-                {
-                        for (int i = 0; i < numeric_param_list.Count; i++) {
-                                named_param_hash[((SqliteParameter) numeric_param_list[i]).ParameterName] = i;
-                        }
-                }
-        }
+       public class SqliteParameterCollection : IDataParameterCollection, IList
+       {
+       
+               #region Fields
+               
+               ArrayList numeric_param_list = new ArrayList();
+               Hashtable named_param_hash = new Hashtable();
+               
+               #endregion
+
+               #region Private Methods
+
+               private void CheckSqliteParam (object value)
+               {
+                       if (!(value is SqliteParameter))
+                               throw new InvalidCastException ("Can only use SqliteParameter objects");
+                       SqliteParameter sqlp = value as SqliteParameter;
+                       if (sqlp.ParameterName == null || sqlp.ParameterName.Length == 0)
+                               sqlp.ParameterName = this.GenerateParameterName();
+                 }
+
+               private void RecreateNamedHash ()
+               {
+                       for (int i = 0; i < numeric_param_list.Count; i++) 
+                       {
+                               named_param_hash[((SqliteParameter) numeric_param_list[i]).ParameterName] = i;
+                       }
+               }
+
+               //FIXME: if the user is calling Insert at various locations with unnamed parameters, this is not going to work....
+               private string GenerateParameterName()
+               {
+                       int             index   = this.Count + 1;
+                       string  name    = String.Empty;
+
+                       while (index > 0)
+                       {
+                               name = ":" + index.ToString();
+                                       if (this.IndexOf(name) == -1)
+                                       index = -1;
+                               else
+                               index++;
+                       }
+                       return name;
+               }
+
+               #endregion
+
+               #region Properties
+               
+               object IList.this[int index] {
+                       get 
+                       {
+                               return this[index];
+                       }
+                       set 
+                       {
+                               CheckSqliteParam (value);
+                               this[index] = (SqliteParameter) value;
+                       }
+               }
+               
+               object IDataParameterCollection.this[string parameterName] {
+                       get 
+                       {
+                               return this[parameterName];
+                       }
+                       set 
+                       {
+                               CheckSqliteParam (value);
+                               this[parameterName] = (SqliteParameter) value;
+                       }
+               }
+               
+               private bool isPrefixed (string parameterName)
+               {
+                       return parameterName.Length > 1 && (parameterName[0] == ':' || parameterName[0] == '$');
+               }
+               
+               public SqliteParameter this[string parameterName] 
+               {
+                       get 
+                       {
+                               if (this.Contains(parameterName))
+                                       return this[(int) named_param_hash[parameterName]];
+                               else if (isPrefixed(parameterName) && this.Contains(parameterName.Substring(1)))
+                                       return this[(int) named_param_hash[parameterName.Substring(1)]];
+                               else
+                                       throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
+                       }
+                       set
+                       {
+                               if (this.Contains(parameterName))
+                                       numeric_param_list[(int) named_param_hash[parameterName]] = value;
+                               else if (parameterName.Length > 1 && this.Contains(parameterName.Substring(1)))
+                                       numeric_param_list[(int) named_param_hash[parameterName.Substring(1)]] = value;
+                               else
+                                       throw new IndexOutOfRangeException("The specified name does not exist: " + parameterName);
+                       }
+               }
+
+               public SqliteParameter this[int parameterIndex]
+               {
+                       get
+                       {
+                               if (this.Count >= parameterIndex+1)
+                                       return (SqliteParameter) numeric_param_list[parameterIndex];
+                               else          
+                                       throw new IndexOutOfRangeException("The specified parameter index does not exist: " + parameterIndex.ToString());
+                       }
+                       set
+                       {
+                               if (this.Count >= parameterIndex+1)
+                                       numeric_param_list[parameterIndex] = value;
+                               else          
+                                       throw new IndexOutOfRangeException("The specified parameter index does not exist: " + parameterIndex.ToString());
+                       }
+               }
+
+
+               public int Count 
+               {
+                       get
+                       {
+                               return this.numeric_param_list.Count;
+                       }
+               }
+
+               bool IList.IsFixedSize
+               {
+                       get
+                       {
+                               return this.numeric_param_list.IsFixedSize;
+                       }
+               }
+
+               bool IList.IsReadOnly
+               {
+                       get
+                       {
+                               return this.numeric_param_list.IsReadOnly;
+                       }
+               }
+
+
+               bool ICollection.IsSynchronized 
+               {
+                       get
+                       {
+                               return this.numeric_param_list.IsSynchronized;
+                       }
+               }
+               
+
+               object ICollection.SyncRoot 
+               {
+                       get
+                       {
+                               return this.numeric_param_list.SyncRoot;
+                       }
+               }
+
+               #endregion
+
+               #region Public Methods
+               
+               public int Add (object value)
+               {
+                       CheckSqliteParam (value);
+                       SqliteParameter sqlp = value as SqliteParameter;
+                       if (named_param_hash.Contains (sqlp.ParameterName))
+                               throw new DuplicateNameException ("Parameter collection already contains the a SqliteParameter with the given ParameterName.");
+                       named_param_hash[sqlp.ParameterName] = numeric_param_list.Add(value);
+                               return (int) named_param_hash[sqlp.ParameterName];
+               }
+
+               public SqliteParameter Add (SqliteParameter param)
+               {
+                       Add ((object)param);
+                       return param;
+               }
+               
+               public SqliteParameter Add (string name, object value)
+               {
+                       return Add (new SqliteParameter (name, value));
+               }
+               
+               public SqliteParameter Add (string name, DbType type)
+               {
+                       return Add (new SqliteParameter (name, type));
+               }
+               
+               public void Clear ()
+               {
+                       numeric_param_list.Clear ();
+                       named_param_hash.Clear ();
+               }
+               
+               public void CopyTo (Array array, int index)
+               {
+                       this.numeric_param_list.CopyTo(array, index);
+               }
+               
+               bool IList.Contains (object value)
+               {
+                       return Contains ((SqliteParameter) value);
+               }
+               
+               public bool Contains (string parameterName)
+               {
+                       return named_param_hash.Contains (parameterName);
+               }
+               
+               public bool Contains (SqliteParameter param)
+               {
+                       return Contains (param.ParameterName);
+               }
+               
+               public IEnumerator GetEnumerator ()
+               {
+                       return this.numeric_param_list.GetEnumerator();
+               }
+               
+               int IList.IndexOf (object param)
+               {
+                       return IndexOf ((SqliteParameter) param);
+               }
+               
+               public int IndexOf (string parameterName)
+               {
+                       if (named_param_hash.Contains(parameterName))
+                               return (int) named_param_hash[parameterName];
+                       else
+                               return -1;
+               }
+               
+               public int IndexOf (SqliteParameter param)
+               {
+                       return IndexOf (param.ParameterName);
+               }
+               
+               public void Insert (int index, object value)
+               {
+                       CheckSqliteParam (value);
+                       if (numeric_param_list.Count == index) 
+                       {
+                               Add (value);
+                               return;
+                       }
+                       
+                       numeric_param_list.Insert (index, value);
+                       RecreateNamedHash ();
+               }
+               
+               public void Remove (object value)
+               {
+                       CheckSqliteParam (value);
+                       RemoveAt ((SqliteParameter) value);
+               }
+               
+               public void RemoveAt (int index)
+               {
+                       RemoveAt (((SqliteParameter) numeric_param_list[index]).ParameterName);
+               }
+               
+               public void RemoveAt (string parameterName)
+               {
+                       if (!named_param_hash.Contains (parameterName))
+                               throw new ApplicationException ("Parameter " + parameterName + " not found");
+                       
+                       numeric_param_list.RemoveAt ((int) named_param_hash[parameterName]);
+                       named_param_hash.Remove (parameterName);
+                       
+                       RecreateNamedHash ();
+               }
+               
+               public void RemoveAt (SqliteParameter param)
+               {
+                       RemoveAt (param.ParameterName);
+               }
+               
+               #endregion
+       }
 }