diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringSynonyms.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringSynonyms.cs index 8d4060e1b4..15c32abe75 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringSynonyms.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringSynonyms.cs @@ -10,12 +10,15 @@ internal static class DbConnectionStringSynonyms internal const string Address = "address"; internal const string App = "app"; internal const string ApplicationIntent = "applicationintent"; + internal const string ColumnEncryption = "columnEncryption"; internal const string ConnectionLifetime = "connection lifetime"; internal const string ConnectionTimeout = "connection timeout"; internal const string ConnectRetryCount = "connectretrycount"; internal const string ConnectRetryInterval = "connectretryinterval"; + internal const string ConnectTimeout = "connecttimeout"; internal const string Database = "database"; internal const string ExtendedProperties = "extended properties"; + internal const string FailoverPartner = "failoverpartner"; internal const string FailoverPartnerSpn = "FailoverPartnerSPN"; internal const string HostNameInCertificate = "hostnameincertificate"; internal const string InitialFileName = "initial file name"; @@ -26,6 +29,7 @@ internal static class DbConnectionStringSynonyms internal const string Net = "net"; internal const string Network = "network"; internal const string NetworkAddress = "network address"; + internal const string PacketSize = "packetsize"; internal const string PersistSecurityInfo = "persistsecurityinfo"; internal const string PoolBlockingPeriod = "poolblockingperiod"; internal const string Pwd = "pwd"; @@ -38,6 +42,7 @@ internal static class DbConnectionStringSynonyms internal const string TrustServerCertificate = "trustservercertificate"; internal const string Uid = "uid"; internal const string User = "user"; + internal const string WorkstationId = "workstationid"; internal const string WsId = "wsid"; } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs index d36863da95..ad05f67830 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs @@ -52,7 +52,7 @@ internal static class TRANSACTIONBINDING internal const string ImplicitUnbind = "Implicit Unbind"; internal const string ExplicitUnbind = "Explicit Unbind"; } - + private static readonly Dictionary s_keywordMap = new Dictionary(StringComparer.InvariantCultureIgnoreCase); @@ -109,9 +109,9 @@ internal static class TRANSACTIONBINDING private static readonly Version s_constTypeSystemAsmVersion11 = new("11.0.0.0"); private readonly string _expandedAttachDBFilename; // expanded during construction so that CreatePermissionSet & Expand are consistent - + #region Constructors - + /// /// Static constructor to do things that we can't do in a single line initialization. /// @@ -125,13 +125,14 @@ static SqlConnectionString() AddKeywordToMap(DbConnectionStringKeywords.ApplicationIntent, DbConnectionStringSynonyms.ApplicationIntent); AddKeywordToMap(DbConnectionStringKeywords.ApplicationName, - DbConnectionStringSynonyms.App); + DbConnectionStringSynonyms.App); AddKeywordToMap(DbConnectionStringKeywords.AttachDbFilename, DbConnectionStringSynonyms.ExtendedProperties, DbConnectionStringSynonyms.InitialFileName); AddKeywordToMap(DbConnectionStringKeywords.AttestationProtocol); AddKeywordToMap(DbConnectionStringKeywords.Authentication); - AddKeywordToMap(DbConnectionStringKeywords.ColumnEncryptionSetting); + AddKeywordToMap(DbConnectionStringKeywords.ColumnEncryptionSetting, + DbConnectionStringSynonyms.ColumnEncryption); AddKeywordToMap(DbConnectionStringKeywords.CommandTimeout); AddKeywordToMap(DbConnectionStringKeywords.ConnectRetryCount, DbConnectionStringSynonyms.ConnectRetryCount); @@ -139,6 +140,7 @@ static SqlConnectionString() DbConnectionStringSynonyms.ConnectRetryInterval); AddKeywordToMap(DbConnectionStringKeywords.ConnectTimeout, DbConnectionStringSynonyms.ConnectionTimeout, + DbConnectionStringSynonyms.ConnectTimeout, DbConnectionStringSynonyms.Timeout); AddKeywordToMap(DbConnectionStringKeywords.ContextConnection); AddKeywordToMap(DbConnectionStringKeywords.CurrentLanguage, @@ -151,7 +153,8 @@ static SqlConnectionString() AddKeywordToMap(DbConnectionStringKeywords.EnclaveAttestationUrl); AddKeywordToMap(DbConnectionStringKeywords.Encrypt); AddKeywordToMap(DbConnectionStringKeywords.Enlist); - AddKeywordToMap(DbConnectionStringKeywords.FailoverPartner); + AddKeywordToMap(DbConnectionStringKeywords.FailoverPartner, + DbConnectionStringSynonyms.FailoverPartner); AddKeywordToMap(DbConnectionStringKeywords.FailoverPartnerSpn, DbConnectionStringSynonyms.FailoverPartnerSpn); AddKeywordToMap(DbConnectionStringKeywords.HostNameInCertificate, @@ -170,7 +173,8 @@ static SqlConnectionString() AddKeywordToMap(DbConnectionStringKeywords.MinPoolSize); AddKeywordToMap(DbConnectionStringKeywords.MultiSubnetFailover, DbConnectionStringSynonyms.MultiSubnetFailover); - AddKeywordToMap(DbConnectionStringKeywords.PacketSize); + AddKeywordToMap(DbConnectionStringKeywords.PacketSize, + DbConnectionStringSynonyms.PacketSize); AddKeywordToMap(DbConnectionStringKeywords.Password, DbConnectionStringSynonyms.Pwd); AddKeywordToMap(DbConnectionStringKeywords.PersistSecurityInfo, @@ -192,6 +196,7 @@ static SqlConnectionString() DbConnectionStringSynonyms.User); AddKeywordToMap(DbConnectionStringKeywords.UserInstance); AddKeywordToMap(DbConnectionStringKeywords.WorkstationId, + DbConnectionStringSynonyms.WorkstationId, DbConnectionStringSynonyms.WsId); #if NETFRAMEWORK @@ -203,7 +208,7 @@ static SqlConnectionString() DbConnectionStringSynonyms.TransparentNetworkIpResolution); #endif } - + internal SqlConnectionString(string connectionString): base(connectionString, s_keywordMap) { #if !NETFRAMEWORK @@ -568,12 +573,12 @@ internal SqlConnectionString(SqlConnectionString connectionOptions, string dataS } #endregion - + internal bool IntegratedSecurity => _integratedSecurity; // @TODO: This is temporary until we can remove DbConnectionString (see SqlClientPermission) internal static IReadOnlyDictionary KeywordMap => s_keywordMap; - + // We always initialize in Async mode so that both synchronous and asynchronous methods // will work. In the future we can deprecate the keyword entirely. internal bool Asynchronous => true; @@ -983,21 +988,21 @@ protected internal override PermissionSet CreatePermissionSet() internal string NetworkLibrary => _networkLibrary; #endif // NETFRAMEWORK - + #region Private Methods - + private static void AddKeywordToMap(string keyword, params string[] synonyms) { // Add mapping of keyword to keyword s_keywordMap.Add(keyword, keyword); - + // Add mapping of synonyms to keyword foreach (string synonym in synonyms) { s_keywordMap.Add(synonym, keyword); } } - + #endregion } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs index 6bc29aee36..ca5fb61cef 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs @@ -273,12 +273,17 @@ private static Dictionary CreateKeywordsDictionary() { DbConnectionStringSynonyms.Uid, Keywords.UserID }, { DbConnectionStringSynonyms.User, Keywords.UserID }, { DbConnectionStringSynonyms.WsId, Keywords.WorkstationID }, + { DbConnectionStringSynonyms.WorkstationId, Keywords.WorkstationID }, { DbConnectionStringSynonyms.ServerSpn, Keywords.ServerSPN }, { DbConnectionStringSynonyms.FailoverPartnerSpn, Keywords.FailoverPartnerSPN }, + { DbConnectionStringSynonyms.ColumnEncryption, Keywords.ColumnEncryptionSetting }, + { DbConnectionStringSynonyms.ConnectTimeout, Keywords.ConnectTimeout }, + { DbConnectionStringSynonyms.FailoverPartner, Keywords.FailoverPartner }, + { DbConnectionStringSynonyms.PacketSize, Keywords.PacketSize }, }; return pairs; } - + // @TODO These methods are completely unnecessary. private static bool ConvertToBoolean(object value) => DbConnectionStringUtilities.ConvertToBoolean(value); @@ -565,7 +570,7 @@ private void Reset(Keywords index) } // @TODO: These methods can be inlined with the property setters. - + private void SetValue(string keyword, bool value) => base[keyword] = value.ToString(); private void SetValue(string keyword, int value) => base[keyword] = value.ToString((System.IFormatProvider)null); diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs index 30e232e88c..a24c330181 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionStringBuilderTest.cs @@ -93,7 +93,12 @@ public partial class SqlConnectionStringBuilderTest [InlineData("Type System Version = Latest")] [InlineData("User Instance = true")] [InlineData("Workstation ID = myworkstation")] + [InlineData("WorkstationID = myworkstation")] [InlineData("WSID = myworkstation")] + [InlineData("ConnectTimeout = 30")] + [InlineData("Initial Catalog = Northwind; FailoverPartner = randomserver.sys.local")] + [InlineData("PacketSize = 8192")] + [InlineData("columnEncryption = Enabled")] [InlineData("Host Name In Certificate = tds.test.com")] [InlineData("HostNameInCertificate = tds.test.com")] [InlineData("Server Certificate = c:\\test.cer")] @@ -937,5 +942,63 @@ internal static void CheckEncryptType(SqlConnectionStringBuilder builder, SqlCon Assert.Equal(expectedValue, builder.Encrypt); } + [Theory] + [InlineData("ConnectTimeout = 45", 45)] + [InlineData("connecttimeout = 45", 45)] + [InlineData("CONNECTTIMEOUT = 45", 45)] + [InlineData("Connect Timeout = 45", 45)] + [InlineData("Connection Timeout = 45", 45)] + [InlineData("Timeout = 45", 45)] + public void ConnectTimeoutSynonymsResolveCorrectly(string connectionString, int expected) + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString); + Assert.Equal(expected, builder.ConnectTimeout); + } + + [Theory] + [InlineData("Initial Catalog = Northwind; FailoverPartner = partner.sys.local")] + [InlineData("Initial Catalog = Northwind; failoverpartner = partner.sys.local")] + [InlineData("Initial Catalog = Northwind; FAILOVERPARTNER = partner.sys.local")] + [InlineData("Initial Catalog = Northwind; Failover Partner = partner.sys.local")] + public void FailoverPartnerSynonymsResolveCorrectly(string connectionString) + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString); + Assert.Equal("partner.sys.local", builder.FailoverPartner); + } + + [Theory] + [InlineData("PacketSize = 16000", 16000)] + [InlineData("packetsize = 16000", 16000)] + [InlineData("PACKETSIZE = 16000", 16000)] + [InlineData("Packet Size = 16000", 16000)] + public void PacketSizeSynonymsResolveCorrectly(string connectionString, int expected) + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString); + Assert.Equal(expected, builder.PacketSize); + } + + [Theory] + [InlineData("WorkstationID = myws")] + [InlineData("workstationid = myws")] + [InlineData("WORKSTATIONID = myws")] + [InlineData("Workstation ID = myws")] + [InlineData("WSID = myws")] + public void WorkstationIdSynonymsResolveCorrectly(string connectionString) + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString); + Assert.Equal("myws", builder.WorkstationID); + } + + [Theory] + [InlineData("columnEncryption = Enabled")] + [InlineData("columnencryption = Enabled")] + [InlineData("COLUMNENCRYPTION = Enabled")] + [InlineData("Column Encryption Setting = Enabled")] + public void ColumnEncryptionSynonymsResolveCorrectly(string connectionString) + { + SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString); + Assert.Equal(SqlConnectionColumnEncryptionSetting.Enabled, builder.ColumnEncryptionSetting); + } + } }