Skip to content

Commit 3737477

Browse files
committed
Enforce a consistent order for connection string options. Fixes #1217
Signed-off-by: Bradley Grainger <[email protected]>
1 parent 4a11c0a commit 3737477

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

src/MySqlConnector/MySqlConnectionStringBuilder.cs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.ComponentModel;
33
using System.Diagnostics.CodeAnalysis;
44
using System.Globalization;
5+
using System.Linq;
56
using System.Text.RegularExpressions;
67
using MySqlConnector.Utilities;
78

@@ -787,6 +788,11 @@ public bool UseXaTransactions
787788

788789
// Other Methods
789790

791+
/// <summary>
792+
/// Returns an <see cref="ICollection"/> that contains the keys in the <see cref="MySqlConnectionStringBuilder"/>.
793+
/// </summary>
794+
public override ICollection Keys => base.Keys.Cast<string>().OrderBy(x => MySqlConnectionStringOption.OptionNames.IndexOf(x)).ToList();
795+
790796
/// <summary>
791797
/// Whether this <see cref="MySqlConnectionStringBuilder"/> contains a set option with the specified name.
792798
/// </summary>
@@ -876,6 +882,8 @@ protected override void GetProperties(Hashtable propertyDescriptors)
876882

877883
internal abstract class MySqlConnectionStringOption
878884
{
885+
public static List<string> OptionNames { get; } = new();
886+
879887
// Connection Options
880888
public static readonly MySqlConnectionStringReferenceOption<string> Server;
881889
public static readonly MySqlConnectionStringValueOption<uint> Port;
@@ -892,9 +900,9 @@ internal abstract class MySqlConnectionStringOption
892900
public static readonly MySqlConnectionStringReferenceOption<string> CertificatePassword;
893901
public static readonly MySqlConnectionStringValueOption<MySqlCertificateStoreLocation> CertificateStoreLocation;
894902
public static readonly MySqlConnectionStringReferenceOption<string> CertificateThumbprint;
895-
public static readonly MySqlConnectionStringReferenceOption<string> SslCa;
896903
public static readonly MySqlConnectionStringReferenceOption<string> SslCert;
897904
public static readonly MySqlConnectionStringReferenceOption<string> SslKey;
905+
public static readonly MySqlConnectionStringReferenceOption<string> SslCa;
898906
public static readonly MySqlConnectionStringReferenceOption<string> TlsVersion;
899907
public static readonly MySqlConnectionStringReferenceOption<string> TlsCipherSuites;
900908

@@ -960,6 +968,7 @@ private static void AddOption(MySqlConnectionStringOption option)
960968
{
961969
foreach (string key in option.m_keys)
962970
s_options.Add(key, option);
971+
OptionNames.Add(option.m_keys[0]);
963972
}
964973

965974
#pragma warning disable CA1065 // Do not raise exceptions in unexpected locations
@@ -1014,8 +1023,12 @@ static MySqlConnectionStringOption()
10141023
keys: new[] { "Certificate Password", "CertificatePassword" },
10151024
defaultValue: ""));
10161025

1017-
AddOption(SslCa = new(
1018-
keys: new[] { "SSL CA", "CACertificateFile", "CA Certificate File", "SslCa", "Ssl-Ca" },
1026+
AddOption(CertificateStoreLocation = new(
1027+
keys: new[] { "Certificate Store Location", "CertificateStoreLocation" },
1028+
defaultValue: MySqlCertificateStoreLocation.None));
1029+
1030+
AddOption(CertificateThumbprint = new(
1031+
keys: new[] { "Certificate Thumbprint", "CertificateThumbprint", "Certificate Thumb Print" },
10191032
defaultValue: ""));
10201033

10211034
AddOption(SslCert = new(
@@ -1026,12 +1039,8 @@ static MySqlConnectionStringOption()
10261039
keys: new[] { "SSL Key", "SslKey", "Ssl-Key" },
10271040
defaultValue: ""));
10281041

1029-
AddOption(CertificateStoreLocation = new(
1030-
keys: new[] { "Certificate Store Location", "CertificateStoreLocation" },
1031-
defaultValue: MySqlCertificateStoreLocation.None));
1032-
1033-
AddOption(CertificateThumbprint = new(
1034-
keys: new[] { "Certificate Thumbprint", "CertificateThumbprint", "Certificate Thumb Print" },
1042+
AddOption(SslCa = new(
1043+
keys: new[] { "SSL CA", "CACertificateFile", "CA Certificate File", "SslCa", "Ssl-Ca" },
10351044
defaultValue: ""));
10361045

10371046
AddOption(TlsVersion = new(

tests/MySqlConnector.Tests/MySqlConnectionStringBuilderTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,22 @@ public void ParseConnectionString()
232232
Assert.True(csb.UseAffectedRows);
233233
Assert.True(csb.UseCompression);
234234
Assert.Equal("username", csb.UserID);
235+
236+
#if !BASELINE
237+
Assert.Equal("Server=db-server;Port=1234;User ID=username;Password=Pass1234;Database=schema_name;Load Balance=Random;" +
238+
"Connection Protocol=NamedPipe;Pipe Name=MyPipe;SSL Mode=VerifyCA;Certificate File=file.pfx;Certificate Password=Pass2345;" +
239+
"Certificate Store Location=CurrentUser;Certificate Thumbprint=thumbprint123;SSL Cert=client-cert.pem;SSL Key=client-key.pem;" +
240+
"SSL CA=ca.pem;TLS Version=\"TLS 1.2, TLS 1.3\";TLS Cipher Suites=TLS_AES_128_CCM_8_SHA256,TLS_RSA_WITH_RC4_128_MD5;" +
241+
"Pooling=False;Connection Lifetime=15;Connection Reset=False;Defer Connection Reset=True;Connection Idle Timeout=30;" +
242+
"Minimum Pool Size=5;Maximum Pool Size=15;Allow Load Local Infile=True;Allow Public Key Retrieval=True;Allow User Variables=True;" +
243+
"Allow Zero DateTime=True;Application Name=\"My Test Application\";Auto Enlist=False;Cancellation Timeout=-1;Character Set=latin1;" +
244+
"Connection Timeout=30;Convert Zero DateTime=True;DateTime Kind=Utc;Default Command Timeout=123;Force Synchronous=True;" +
245+
"GUID Format=TimeSwapBinary16;Ignore Command Transaction=True;Ignore Prepare=True;Interactive Session=True;Keep Alive=90;" +
246+
"No Backslash Escapes=True;Old Guids=True;Persist Security Info=True;Pipelining=False;Server Redirection Mode=Required;" +
247+
"Server RSA Public Key File=rsa.pem;Server SPN=mariadb/[email protected];Treat Tiny As Boolean=False;" +
248+
"Use Affected Rows=True;Use Compression=True;Use XA Transactions=False",
249+
csb.ConnectionString);
250+
#endif
235251
}
236252

237253
[Fact]

tests/SideBySide/ConnectionTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public void CloneWithUsesNewConnectionString(bool openConnection)
208208
if (openConnection)
209209
connection.Open();
210210
using var connection2 = connection.CloneWith("user=root;password=pass;server=example.com;database=test");
211-
Assert.Equal("User ID=root;Password=pass;Server=example.com;Database=test", connection2.ConnectionString);
211+
Assert.Equal("Server=example.com;User ID=root;Password=pass;Database=test", connection2.ConnectionString);
212212
}
213213

214214
[Fact]

0 commit comments

Comments
 (0)