Skip to content

Commit e99d7cb

Browse files
committed
Fix MySqlParameter.Clone; add tests.
Add overload of Clone with strongly-typed return value. Implement Clone by setting fields, not by invoking a constructor (so that HasSetDbType is initialised correctly). Signed-off-by: Bradley Grainger <[email protected]>
1 parent 0d344d2 commit e99d7cb

File tree

3 files changed

+121
-15
lines changed

3 files changed

+121
-15
lines changed

docs/content/tutorials/migrating-from-connector-net.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,4 @@ The following bugs in Connector/NET are fixed by switching to MySqlConnector. (~
136136
* [#91754](https://bugs.mysql.com/bug.php?id=91754): Inserting 16MiB `BLOB` shifts it by four bytes when prepared
137137
* [#91770](https://bugs.mysql.com/bug.php?id=91770): `TIME(n)` column loses microseconds with prepared command
138138
* [#92367](https://bugs.mysql.com/bug.php?id=92367): `MySqlDataReader.GetDateTime` and `GetValue` return inconsistent values
139+
* [#92734](https://bugs.mysql.com/bug.php?id=92734): `MySqlParameter.Clone` doesn't copy all property values

src/MySqlConnector/MySql.Data.MySqlClient/MySqlParameter.cs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010

1111
namespace MySql.Data.MySqlClient
1212
{
13-
14-
#if !NETSTANDARD1_3
15-
public sealed class MySqlParameter : DbParameter, IDbDataParameter, ICloneable
16-
#else
1713
public sealed class MySqlParameter : DbParameter, IDbDataParameter
14+
#if !NETSTANDARD1_3
15+
, ICloneable
1816
#endif
1917
{
2018
public MySqlParameter()
@@ -159,24 +157,40 @@ public override void ResetDbType()
159157
HasSetDbType = false;
160158
}
161159

160+
public MySqlParameter Clone() => new MySqlParameter(this);
161+
162+
#if !NETSTANDARD1_3
163+
object ICloneable.Clone() => Clone();
164+
#endif
165+
162166
internal MySqlParameter WithParameterName(string parameterName) => new MySqlParameter(this, parameterName);
163167

164-
private MySqlParameter(MySqlParameter other, string parameterName)
168+
private MySqlParameter(MySqlParameter other)
165169
{
166170
m_dbType = other.m_dbType;
167171
m_mySqlDbType = other.m_mySqlDbType;
168172
m_direction = other.m_direction;
169173
HasSetDbType = other.HasSetDbType;
170174
IsNullable = other.IsNullable;
171175
Size = other.Size;
172-
ParameterName = parameterName ?? other.ParameterName;
173-
Value = other.Value;
174-
#if !NET45
176+
m_name = other.m_name;
177+
NormalizedParameterName = other.NormalizedParameterName;
178+
m_value = other.m_value;
175179
Precision = other.Precision;
176180
Scale = other.Scale;
181+
SourceColumn = other.SourceColumn;
182+
SourceColumnNullMapping = other.SourceColumnNullMapping;
183+
#if !NETSTANDARD1_3
184+
SourceVersion = other.SourceVersion;
177185
#endif
178186
}
179187

188+
private MySqlParameter(MySqlParameter other, string parameterName)
189+
: this(other)
190+
{
191+
ParameterName = parameterName ?? throw new ArgumentNullException(nameof(parameterName));
192+
}
193+
180194
internal bool HasSetDirection => m_direction.HasValue;
181195

182196
internal bool HasSetDbType { get; set; }
@@ -617,13 +631,6 @@ private static void WriteTime(ByteBufferWriter writer, TimeSpan timeSpan)
617631
}
618632
}
619633

620-
#if !NETSTANDARD1_3
621-
public object Clone()
622-
{
623-
return new MySqlParameter(ParameterName, MySqlDbType, Size, Direction, IsNullable, Precision, Scale, SourceColumn, SourceVersion, Value);
624-
}
625-
#endif
626-
627634
static readonly byte[] s_nullBytes = { 0x4E, 0x55, 0x4C, 0x4C }; // NULL
628635
static readonly byte[] s_trueBytes = { 0x74, 0x72, 0x75, 0x65 }; // true
629636
static readonly byte[] s_falseBytes = { 0x66, 0x61, 0x6C, 0x73, 0x65 }; // false

tests/SideBySide/ParameterTests.cs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,104 @@ public void ConstructorEverything()
208208
}
209209
#endif
210210

211+
[Fact]
212+
public void CloneParameterName()
213+
{
214+
var parameter = new MySqlParameter { ParameterName = "test" };
215+
var clone = parameter.Clone();
216+
Assert.Equal(parameter.ParameterName, clone.ParameterName);
217+
}
218+
219+
[Fact]
220+
public void CloneDbType()
221+
{
222+
var parameter = new MySqlParameter { DbType = DbType.Int64 };
223+
var clone = parameter.Clone();
224+
Assert.Equal(parameter.DbType, clone.DbType);
225+
}
226+
227+
[Fact]
228+
public void CloneMySqlDbType()
229+
{
230+
var parameter = new MySqlParameter { MySqlDbType = MySqlDbType.MediumText };
231+
var clone = parameter.Clone();
232+
Assert.Equal(parameter.MySqlDbType, clone.MySqlDbType);
233+
}
234+
235+
[Fact]
236+
public void CloneDirection()
237+
{
238+
var parameter = new MySqlParameter { Direction = ParameterDirection.InputOutput };
239+
var clone = parameter.Clone();
240+
Assert.Equal(parameter.Direction, clone.Direction);
241+
}
242+
243+
[SkippableFact(Baseline = "https://bugs.mysql.com/bug.php?id=92734")]
244+
public void CloneIsNullable()
245+
{
246+
var parameter = new MySqlParameter { IsNullable = true };
247+
var clone = parameter.Clone();
248+
Assert.Equal(parameter.IsNullable, clone.IsNullable);
249+
}
250+
251+
[SkippableFact(Baseline = "https://bugs.mysql.com/bug.php?id=92734")]
252+
public void ClonePrecision()
253+
{
254+
var parameter = new MySqlParameter { Precision = 10 };
255+
var clone = parameter.Clone();
256+
Assert.Equal(parameter.Precision, clone.Precision);
257+
}
258+
259+
[SkippableFact(Baseline = "https://bugs.mysql.com/bug.php?id=92734")]
260+
public void CloneScale()
261+
{
262+
var parameter = new MySqlParameter { Scale = 12 };
263+
var clone = parameter.Clone();
264+
Assert.Equal(parameter.Scale, clone.Scale);
265+
}
266+
267+
[SkippableFact(Baseline = "https://bugs.mysql.com/bug.php?id=92734")]
268+
public void CloneSize()
269+
{
270+
var parameter = new MySqlParameter { Size = 8 };
271+
var clone = parameter.Clone();
272+
Assert.Equal(parameter.Size, clone.Size);
273+
}
274+
275+
[Fact]
276+
public void CloneSourceColumn()
277+
{
278+
var parameter = new MySqlParameter { SourceColumn = "test" };
279+
var clone = parameter.Clone();
280+
Assert.Equal(parameter.SourceColumn, clone.SourceColumn);
281+
}
282+
283+
[SkippableFact(Baseline = "https://bugs.mysql.com/bug.php?id=92734")]
284+
public void CloneSourceColumnNullMapping()
285+
{
286+
var parameter = new MySqlParameter { SourceColumnNullMapping = true };
287+
var clone = parameter.Clone();
288+
Assert.Equal(parameter.SourceColumnNullMapping, clone.SourceColumnNullMapping);
289+
}
290+
291+
#if !NETCOREAPP1_1_2
292+
[Fact]
293+
public void CloneSourceVersion()
294+
{
295+
var parameter = new MySqlParameter { SourceVersion = DataRowVersion.Proposed };
296+
var clone = parameter.Clone();
297+
Assert.Equal(parameter.SourceVersion, clone.SourceVersion);
298+
}
299+
#endif
300+
301+
[Fact]
302+
public void CloneValue()
303+
{
304+
var parameter = new MySqlParameter { Value = "test" };
305+
var clone = parameter.Clone();
306+
Assert.Equal(parameter.Value, clone.Value);
307+
}
308+
211309
[Theory]
212310
[InlineData(1, DbType.Int32, MySqlDbType.Int32)]
213311
[InlineData(1.0, DbType.Double, MySqlDbType.Double)]

0 commit comments

Comments
 (0)