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 TestSuite | rburnett | 19 Mar |