MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:rburnett Date:March 19 2007 10:34pm
Subject:Connector/NET commit: r638 - in branches/5.0: . Driver/Source TestSuite
View as plain text  
Modified:
   branches/5.0/CHANGES
   branches/5.0/Driver/Source/parameter_collection.cs
   branches/5.0/TestSuite/ParameterTests.cs
Log:
Bug #27187 cmd.Parameters.RemoveAt("Id") will cause an error if the last item is requested 

Refactored the parameter collection code to update the hashes when a parameter is removed or inserted at a specific location.

Modified: branches/5.0/CHANGES
===================================================================
--- branches/5.0/CHANGES	2007-03-19 18:09:37 UTC (rev 637)
+++ branches/5.0/CHANGES	2007-03-19 22:34:31 UTC (rev 638)
@@ -4,6 +4,7 @@
   ----------
   Bug #27135 MySqlParameterCollection and parameters added with Insert Method 
   Bug #27253 Installer : Company info is different 
+  Bug #27187 cmd.Parameters.RemoveAt("Id") will cause an error if the last item is requested   
   
 Version 5.0.5 3/5/2007
 

Modified: branches/5.0/Driver/Source/parameter_collection.cs
===================================================================
--- branches/5.0/Driver/Source/parameter_collection.cs	2007-03-19 18:09:37 UTC (rev 637)
+++ branches/5.0/Driver/Source/parameter_collection.cs	2007-03-19 22:34:31 UTC (rev 638)
@@ -36,20 +36,17 @@
 #endif
 	public sealed class MySqlParameterCollection : DbParameterCollection
 	{
-		private ArrayList items = new ArrayList();
+        private ArrayList items = new ArrayList();
+        private Hashtable indexHash;
 		private char paramMarker = '?';
-		private Hashtable ciHash;
-		private Hashtable hash;
-        private int returnParameterIndex;
 
 		internal MySqlParameterCollection()
 		{
-			hash = new Hashtable();
 #if NET20
-			ciHash = new Hashtable(StringComparer.CurrentCultureIgnoreCase);
+			indexHash = new Hashtable(StringComparer.CurrentCultureIgnoreCase);
 #else
-			ciHash = new Hashtable(new CaseInsensitiveHashCodeProvider(),
-			new CaseInsensitiveComparer());
+			indexHash = new Hashtable(new CaseInsensitiveHashCodeProvider(),
+			    new CaseInsensitiveComparer());
 #endif
             Clear();
 		}
@@ -93,18 +90,6 @@
             return InternalAdd(value, -1);
 		}
 
-		private MySqlParameter AddReturnParameter(MySqlParameter value)
-		{
-            if (returnParameterIndex != -1)
-			{
-				items[returnParameterIndex] = value;
-				return value;
-			}
-
-			returnParameterIndex = items.Add(value);
-            return value;
-		}
-
 		/// <summary>
 		/// Adds a <see cref="MySqlParameter"/> to the <see cref="MySqlParameterCollection"/> given the specified parameter name and value.
 		/// </summary>
@@ -174,7 +159,7 @@
 
 		void CheckIndex(int index)
 		{
-			if (index < 0 || index >= items.Count)
+			if (index < 0 || index >= Count)
 				throw new IndexOutOfRangeException("Parameter index is out of range.");
 		}
 
@@ -194,7 +179,7 @@
 				{
 					string newParameterName = parameterName.Substring(1);
 					index = IndexOf(newParameterName);
-					if (index != -1)
+					if (index == -1)
                         return (DbParameter)items[index];
 				}
 				throw new ArgumentException("Parameter '" + parameterName + "' not found in the collection.");
@@ -220,23 +205,10 @@
 		{
 			CheckIndex(index);
             MySqlParameter p = (MySqlParameter)items[index];
-            if (p.Direction == ParameterDirection.ReturnValue)
-                returnParameterIndex = -1;
-            else
-            {
-                hash.Remove(p.ParameterName);
-                ciHash.Remove(p.ParameterName);
-            }
-
+            
+            indexHash.Remove(p.ParameterName);
 			items[index] = (MySqlParameter)value;
-            p = (MySqlParameter)value;
-            if (p.Direction == ParameterDirection.ReturnValue)
-                returnParameterIndex = index;
-            else
-            {
-                hash.Add(p.ParameterName, index);
-                ciHash.Add(p.ParameterName, index);
-            }
+            indexHash.Add(value.ParameterName, index);
         }
 
 		/// <summary>
@@ -266,9 +238,7 @@
             foreach (MySqlParameter p in items)
                 p.Collection = null;
 			items.Clear();
-			hash.Clear();
-			ciHash.Clear();
-            returnParameterIndex = -1;
+			indexHash.Clear();
 		}
 
 		/// <summary>
@@ -326,21 +296,10 @@
 		/// <returns>The zero-based location of the <see cref="MySqlParameter"/> in the collection.</returns>
 		public override int IndexOf(string parameterName)
 		{
-			object o = hash[parameterName];
-            if (o != null)
-                return (int)o;
-
-			o = ciHash[parameterName];
-            if (o != null)
-                return (int)o;
-
-            if (returnParameterIndex != -1)
-            {
-                MySqlParameter p = (MySqlParameter)items[returnParameterIndex];
-                if (String.Compare(parameterName, p.ParameterName, true) == 0)
-                    return returnParameterIndex;
-            }
-			return -1;
+            object o = indexHash[parameterName];
+            if (o == null)
+                return -1;
+            return (int)o;
 		}
 
 		/// <summary>
@@ -399,14 +358,12 @@
 		/// <param name="value"></param>
 		public override void Remove(object value)
 		{
-			items.Remove(value);
-
             MySqlParameter p = (value as MySqlParameter);
-            hash.Remove(p.ParameterName);
-            ciHash.Remove(p.ParameterName);
             p.Collection = null;
-            if (p.Direction == ParameterDirection.ReturnValue)
-                returnParameterIndex = -1;
+            int index = IndexOf(p);
+			items.Remove(p);
+            indexHash.Remove(p.ParameterName);
+            AdjustHash(index, false);
 		}
 
 		/// <summary>
@@ -443,13 +400,9 @@
 
         internal void ParameterNameChanged(MySqlParameter p, string oldName, string newName)
         {
-            if (p.Direction == ParameterDirection.ReturnValue)
-                return;
             int index = IndexOf(oldName);
-            hash.Remove(oldName);
-            ciHash.Remove(oldName);
-            hash.Add(newName, index);
-            ciHash.Add(newName, index);
+            indexHash.Remove(oldName);
+            indexHash.Add(newName, index);
         }
 
         private MySqlParameter InternalAdd(MySqlParameter value, int index)
@@ -457,34 +410,44 @@
             if (value == null)
                 throw new ArgumentException("The MySqlParameterCollection only accepts non-null MySqlParameter type objects.", "value");
 
-            if (value.Direction == ParameterDirection.ReturnValue)
-                return AddReturnParameter(value);
-
-            string inComingName = value.ParameterName.ToLower();
+            // make sure we don't already have a parameter with this name
+            string inComingName = value.ParameterName;
+            if (indexHash.ContainsKey(inComingName))
+                throw new MySqlException(
+                    String.Format(Resources.ParameterAlreadyDefined, value.ParameterName));
             if (inComingName[0] == paramMarker)
                 inComingName = inComingName.Substring(1, inComingName.Length - 1);
+            if (indexHash.ContainsKey(inComingName))
+                throw new MySqlException(
+                    String.Format(Resources.ParameterAlreadyDefined, value.ParameterName));
 
-            for (int i = 0; i < items.Count; i++)
-            {
-                MySqlParameter p = (MySqlParameter)items[i];
-                string name = p.ParameterName.ToLower();
-                if (name[0] == paramMarker)
-                    name = name.Substring(1, name.Length - 1);
-                if (name == inComingName)
-                {
-                    throw new MySqlException(
-                        String.Format(Resources.ParameterAlreadyDefined, value.ParameterName));
-                }
-            }
-
             if (index == -1)
+            {
                 index = items.Add(value);
+                indexHash.Add(value.ParameterName, index);
+            }
             else
+            {
                 items.Insert(index, value);
-            hash.Add(value.ParameterName, index);
-            ciHash.Add(value.ParameterName, index);
+                AdjustHash(index, true);
+                indexHash.Add(value.ParameterName, index);
+            }
+
             value.Collection = this;
             return value;
         }
+
+        private void AdjustHash(int keyIndex, bool addEntry)
+        {
+            for (int i=0; i < Count; i++)
+            {
+                MySqlParameter p = (MySqlParameter)items[i];
+                if (!indexHash.ContainsKey(p.ParameterName))
+                    return;
+                int index = (int)indexHash[p.ParameterName];
+                if (index < keyIndex) continue;
+                indexHash[p.ParameterName] = addEntry ? ++index : --index;
+            }
+        }
 	}
 }

Modified: branches/5.0/TestSuite/ParameterTests.cs
===================================================================
--- branches/5.0/TestSuite/ParameterTests.cs	2007-03-19 18:09:37 UTC (rev 637)
+++ branches/5.0/TestSuite/ParameterTests.cs	2007-03-19 22:34:31 UTC (rev 638)
@@ -490,5 +490,23 @@
             MySqlParameter p = cmd.Parameters["?id"];
             Assert.AreEqual("?id", p.ParameterName);
         }
+
+        /// <summary>
+        /// Bug #27187 cmd.Parameters.RemoveAt("Id") will cause an error if the last item is requested 
+        /// </summary>
+        [Test]
+        public void FindParameterAfterRemoval()
+        {
+            MySqlCommand cmd = new MySqlCommand();
+
+            cmd.Parameters.Add("?id1", MySqlDbType.Int32);
+            cmd.Parameters.Add("?id2", MySqlDbType.Int32);
+            cmd.Parameters.Add("?id3", MySqlDbType.Int32);
+            cmd.Parameters.Add("?id4", MySqlDbType.Int32);
+            cmd.Parameters.Add("?id5", MySqlDbType.Int32);
+            cmd.Parameters.Add("?id6", MySqlDbType.Int32);
+            cmd.Parameters.RemoveAt("?id1");
+            MySqlParameter p = cmd.Parameters["?id6"];
+        }
     }
 }

Thread
Connector/NET commit: r638 - in branches/5.0: . Driver/Source TestSuiterburnett19 Mar