Skip to content

Commit 999d982

Browse files
committed
Fix implementation of Insert. Fixes #869
1 parent 1bb0eba commit 999d982

File tree

4 files changed

+180
-9
lines changed

4 files changed

+180
-9
lines changed

src/MySqlConnector/MySqlParameterCollection.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@ public MySqlParameter Add(string parameterName, DbType dbType)
2424
ParameterName = parameterName,
2525
DbType = dbType,
2626
};
27-
AddParameter(parameter);
27+
AddParameter(parameter, m_parameters.Count);
2828
return parameter;
2929
}
3030

3131
public override int Add(object value)
3232
{
33-
AddParameter((MySqlParameter) (value ?? throw new ArgumentNullException(nameof(value))));
33+
AddParameter((MySqlParameter) (value ?? throw new ArgumentNullException(nameof(value))), m_parameters.Count);
3434
return m_parameters.Count - 1;
3535
}
3636

3737
public MySqlParameter Add(MySqlParameter parameter)
3838
{
39-
AddParameter(parameter ?? throw new ArgumentNullException(nameof(parameter)));
39+
AddParameter(parameter ?? throw new ArgumentNullException(nameof(parameter)), m_parameters.Count);
4040
return parameter;
4141
}
4242

@@ -56,7 +56,7 @@ public MySqlParameter AddWithValue(string parameterName, object? value)
5656
ParameterName = parameterName,
5757
Value = value
5858
};
59-
AddParameter(parameter);
59+
AddParameter(parameter, m_parameters.Count);
6060
return parameter;
6161
}
6262

@@ -100,7 +100,7 @@ internal int NormalizedIndexOf(string? parameterName)
100100
return m_nameToIndex.TryGetValue(normalizedName, out var index) ? index : -1;
101101
}
102102

103-
public override void Insert(int index, object value) => m_parameters.Insert(index, (MySqlParameter) (value ?? throw new ArgumentNullException(nameof(value))));
103+
public override void Insert(int index, object value) => AddParameter((MySqlParameter) (value ?? throw new ArgumentNullException(nameof(value))), index);
104104

105105
#if !NETSTANDARD1_3
106106
public override bool IsFixedSize => false;
@@ -173,13 +173,21 @@ internal void ChangeParameterName(MySqlParameter parameter, string oldName, stri
173173
}
174174
}
175175

176-
private void AddParameter(MySqlParameter parameter)
176+
private void AddParameter(MySqlParameter parameter, int index)
177177
{
178178
if (!string.IsNullOrEmpty(parameter.NormalizedParameterName) && NormalizedIndexOf(parameter.NormalizedParameterName) != -1)
179179
throw new MySqlException(@"Parameter '{0}' has already been defined.".FormatInvariant(parameter.ParameterName));
180-
m_parameters.Add(parameter);
180+
if (index < m_parameters.Count)
181+
{
182+
foreach (var pair in m_nameToIndex.ToList())
183+
{
184+
if (pair.Value >= index)
185+
m_nameToIndex[pair.Key] = pair.Value + 1;
186+
}
187+
}
188+
m_parameters.Insert(index, parameter);
181189
if (!string.IsNullOrEmpty(parameter.NormalizedParameterName))
182-
m_nameToIndex[parameter.NormalizedParameterName] = m_parameters.Count - 1;
190+
m_nameToIndex[parameter.NormalizedParameterName] = index;
183191
parameter.ParameterCollection = this;
184192
}
185193

tests/MySqlConnector.Tests/MySqlConnector.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
<ItemGroup Condition=" '$(Configuration)' == 'Baseline' ">
3535
<PackageReference Include="MySql.Data" Version="8.0.21" />
36-
<Compile Remove="ByteBufferWriterTests.cs;CachedProcedureTests.cs;ConnectionTests.cs;FakeMySqlServer.cs;FakeMySqlServerConnection.cs;LoadBalancerTests.cs;MySqlExceptionTests.cs;NormalizeTests.cs;ServerVersionTests.cs;StatementPreparerTests.cs;TypeMapperTests.cs;UtilityTests.cs" />
36+
<Compile Remove="ByteBufferWriterTests.cs;CachedProcedureTests.cs;ConnectionTests.cs;FakeMySqlServer.cs;FakeMySqlServerConnection.cs;LoadBalancerTests.cs;MySqlExceptionTests.cs;MySqlParameterCollectionNameToIndexTests.cs;NormalizeTests.cs;ServerVersionTests.cs;StatementPreparerTests.cs;TypeMapperTests.cs;UtilityTests.cs" />
3737
</ItemGroup>
3838

3939
<ItemGroup Condition=" '$(TargetFramework)' == 'net462' ">
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
using Xunit;
2+
3+
namespace MySqlConnector.Tests
4+
{
5+
public class MySqlParameterCollectionNameToIndexTests
6+
{
7+
public MySqlParameterCollectionNameToIndexTests()
8+
{
9+
m_collection = new MySqlParameterCollection
10+
{
11+
new MySqlParameter { ParameterName = "A", Value = 1 },
12+
new MySqlParameter { ParameterName = "B", Value = 2 },
13+
new MySqlParameter { ParameterName = "C", Value = 3 },
14+
};
15+
}
16+
17+
[Fact]
18+
public void IgnoreCase()
19+
{
20+
Assert.Equal(0, m_collection.NormalizedIndexOf("a"));
21+
Assert.Equal(1, m_collection.NormalizedIndexOf("b"));
22+
Assert.Equal(2, m_collection.NormalizedIndexOf("c"));
23+
}
24+
25+
[Fact]
26+
public void RemoveFirst()
27+
{
28+
m_collection.Remove(m_collection[0]);
29+
Assert.Equal(-1, m_collection.NormalizedIndexOf("A"));
30+
Assert.Equal(0, m_collection.NormalizedIndexOf("B"));
31+
Assert.Equal(1, m_collection.NormalizedIndexOf("C"));
32+
}
33+
34+
[Fact]
35+
public void RemoveSecond()
36+
{
37+
m_collection.Remove(m_collection[1]);
38+
Assert.Equal(0, m_collection.NormalizedIndexOf("A"));
39+
Assert.Equal(-1, m_collection.NormalizedIndexOf("B"));
40+
Assert.Equal(1, m_collection.NormalizedIndexOf("C"));
41+
}
42+
43+
[Fact]
44+
public void RemoveLast()
45+
{
46+
m_collection.Remove(m_collection[2]);
47+
Assert.Equal(0, m_collection.NormalizedIndexOf("A"));
48+
Assert.Equal(1, m_collection.NormalizedIndexOf("B"));
49+
Assert.Equal(-1, m_collection.NormalizedIndexOf("C"));
50+
}
51+
52+
[Fact]
53+
public void RemoveAtBeginning()
54+
{
55+
m_collection.RemoveAt(0);
56+
Assert.Equal(-1, m_collection.NormalizedIndexOf("A"));
57+
Assert.Equal(0, m_collection.NormalizedIndexOf("B"));
58+
Assert.Equal(1, m_collection.NormalizedIndexOf("C"));
59+
}
60+
61+
[Fact]
62+
public void RemoveAtMiddle()
63+
{
64+
m_collection.RemoveAt(1);
65+
Assert.Equal(0, m_collection.NormalizedIndexOf("A"));
66+
Assert.Equal(-1, m_collection.NormalizedIndexOf("B"));
67+
Assert.Equal(1, m_collection.NormalizedIndexOf("C"));
68+
}
69+
70+
[Fact]
71+
public void RemoveAtEnd()
72+
{
73+
m_collection.RemoveAt(2);
74+
Assert.Equal(0, m_collection.NormalizedIndexOf("A"));
75+
Assert.Equal(1, m_collection.NormalizedIndexOf("B"));
76+
Assert.Equal(-1, m_collection.NormalizedIndexOf("C"));
77+
}
78+
79+
[Fact]
80+
public void InsertBeginning()
81+
{
82+
m_collection.Insert(0, new MySqlParameter { ParameterName = "D", Value = 4 });
83+
Assert.Equal(1, m_collection.NormalizedIndexOf("A"));
84+
Assert.Equal(2, m_collection.NormalizedIndexOf("B"));
85+
Assert.Equal(3, m_collection.NormalizedIndexOf("C"));
86+
Assert.Equal(0, m_collection.NormalizedIndexOf("D"));
87+
}
88+
89+
[Fact]
90+
public void InsertMiddle()
91+
{
92+
m_collection.Insert(1, new MySqlParameter { ParameterName = "D", Value = 4 });
93+
Assert.Equal(0, m_collection.NormalizedIndexOf("A"));
94+
Assert.Equal(2, m_collection.NormalizedIndexOf("B"));
95+
Assert.Equal(3, m_collection.NormalizedIndexOf("C"));
96+
Assert.Equal(1, m_collection.NormalizedIndexOf("D"));
97+
}
98+
99+
[Fact]
100+
public void InsertEnd()
101+
{
102+
m_collection.Insert(3, new MySqlParameter { ParameterName = "D", Value = 4 });
103+
Assert.Equal(0, m_collection.NormalizedIndexOf("A"));
104+
Assert.Equal(1, m_collection.NormalizedIndexOf("B"));
105+
Assert.Equal(2, m_collection.NormalizedIndexOf("C"));
106+
Assert.Equal(3, m_collection.NormalizedIndexOf("D"));
107+
}
108+
109+
[Fact]
110+
public void AddEnd()
111+
{
112+
m_collection.Add(new MySqlParameter { ParameterName = "D", Value = 4 });
113+
Assert.Equal(0, m_collection.NormalizedIndexOf("A"));
114+
Assert.Equal(1, m_collection.NormalizedIndexOf("B"));
115+
Assert.Equal(2, m_collection.NormalizedIndexOf("C"));
116+
Assert.Equal(3, m_collection.NormalizedIndexOf("D"));
117+
}
118+
119+
[Fact]
120+
public void ChangeParameter()
121+
{
122+
m_collection[1] = new MySqlParameter { ParameterName = "D", Value = 4 };
123+
Assert.Equal(0, m_collection.NormalizedIndexOf("A"));
124+
Assert.Equal(-1, m_collection.NormalizedIndexOf("B"));
125+
Assert.Equal(2, m_collection.NormalizedIndexOf("C"));
126+
Assert.Equal(1, m_collection.NormalizedIndexOf("D"));
127+
}
128+
129+
MySqlParameterCollection m_collection;
130+
}
131+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#if BASELINE
2+
using MySql.Data.MySqlClient;
3+
#endif
4+
using System;
5+
using Xunit;
6+
7+
namespace MySqlConnector.Tests
8+
{
9+
public class MySqlParameterCollectionTests
10+
{
11+
public MySqlParameterCollectionTests()
12+
{
13+
m_collection = new MySqlCommand().Parameters;
14+
}
15+
16+
#if !BASELINE // -1 adds it to the end of the collection
17+
[Fact]
18+
public void InsertAtNegative() => Assert.Throws<ArgumentOutOfRangeException>(() => m_collection.Insert(-1, new MySqlParameter()));
19+
#endif
20+
21+
[Fact]
22+
public void InsertPastEnd() => Assert.Throws<ArgumentOutOfRangeException>(() => m_collection.Insert(1, new MySqlParameter()));
23+
24+
[Fact]
25+
public void RemoveAtNegative() => Assert.Throws<ArgumentOutOfRangeException>(() => m_collection.RemoveAt(-1));
26+
27+
[Fact]
28+
public void RemoveAtEnd() => Assert.Throws<ArgumentOutOfRangeException>(() => m_collection.RemoveAt(0));
29+
30+
MySqlParameterCollection m_collection;
31+
}
32+
}

0 commit comments

Comments
 (0)