diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
index c35899a762..b56e1be1b6 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -53,12 +53,30 @@
Microsoft\Data\Common\BitConverterCompatible.cs
+
+ Microsoft\Data\Common\ConnectionString\AttestationProtocolUtilities.cs
+
+
+ Microsoft\Data\Common\ConnectionString\DbConnectionStringDefaults.cs
+
+
+ Microsoft\Data\Common\ConnectionString\DbConnectionStringKeywords.cs
+
+
+ Microsoft\Data\Common\ConnectionString\DbConnectionStringSynonyms.cs
+
+
+ Microsoft\Data\Common\ConnectionString\DbConnectionStringUtilities.cs
+
+
+ Microsoft\Data\Common\ConnectionString\IpAddressPreferenceUtilities.cs
+
+
+ Microsoft\Data\Common\ConnectionString\PoolBlockingUtilities.cs
+
Microsoft\Data\Common\DbConnectionOptions.Common.cs
-
- Microsoft\Data\Common\DbConnectionStringCommon.cs
-
Microsoft\Data\Common\MultipartIdentifier.cs
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Common/DbConnectionOptions.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Common/DbConnectionOptions.cs
index 759696d471..443b7e6734 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Common/DbConnectionOptions.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Common/DbConnectionOptions.cs
@@ -5,6 +5,7 @@
using System;
using System.IO;
using System.Text;
+using Microsoft.Data.Common.ConnectionString;
namespace Microsoft.Data.Common
{
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs
index 56835611de..bb568f1f9d 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs
@@ -194,19 +194,19 @@ public SqlConnection(string connectionString, SqlCredential credential) : this()
}
else if (UsesActiveDirectoryManagedIdentity(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringBuilderUtil.ActiveDirectoryManagedIdentityString);
+ throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringUtilities.ActiveDirectoryManagedIdentityString);
}
else if (UsesActiveDirectoryMSI(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringBuilderUtil.ActiveDirectoryMSIString);
+ throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringUtilities.ActiveDirectoryMSIString);
}
else if (UsesActiveDirectoryDefault(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString);
+ throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringUtilities.ActiveDirectoryDefaultString);
}
else if (UsesActiveDirectoryWorkloadIdentity(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringBuilderUtil.ActiveDirectoryWorkloadIdentityString);
+ throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringUtilities.ActiveDirectoryWorkloadIdentityString);
}
Credential = credential;
@@ -621,19 +621,19 @@ public override string ConnectionString
}
else if (UsesActiveDirectoryManagedIdentity(connectionOptions))
{
- throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringBuilderUtil.ActiveDirectoryManagedIdentityString);
+ throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringUtilities.ActiveDirectoryManagedIdentityString);
}
else if (UsesActiveDirectoryMSI(connectionOptions))
{
- throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringBuilderUtil.ActiveDirectoryMSIString);
+ throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringUtilities.ActiveDirectoryMSIString);
}
else if (UsesActiveDirectoryDefault(connectionOptions))
{
- throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString);
+ throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringUtilities.ActiveDirectoryDefaultString);
}
else if (UsesActiveDirectoryWorkloadIdentity(connectionOptions))
{
- throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringBuilderUtil.ActiveDirectoryWorkloadIdentityString);
+ throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringUtilities.ActiveDirectoryWorkloadIdentityString);
}
CheckAndThrowOnInvalidCombinationOfConnectionStringAndSqlCredential(connectionOptions);
@@ -1005,19 +1005,19 @@ public SqlCredential Credential
}
else if (UsesActiveDirectoryManagedIdentity(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringBuilderUtil.ActiveDirectoryManagedIdentityString);
+ throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringUtilities.ActiveDirectoryManagedIdentityString);
}
else if (UsesActiveDirectoryMSI(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringBuilderUtil.ActiveDirectoryMSIString);
+ throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringUtilities.ActiveDirectoryMSIString);
}
else if (UsesActiveDirectoryDefault(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString);
+ throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringUtilities.ActiveDirectoryDefaultString);
}
else if (UsesActiveDirectoryWorkloadIdentity(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringBuilderUtil.ActiveDirectoryWorkloadIdentityString);
+ throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringUtilities.ActiveDirectoryWorkloadIdentityString);
}
CheckAndThrowOnInvalidCombinationOfConnectionStringAndSqlCredential(connectionOptions);
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
index 20f02e7204..415b3825e0 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -234,8 +234,26 @@
Microsoft\Data\Common\BitConverterCompatible.cs
-
- Microsoft\Data\Common\DbConnectionStringCommon.cs
+
+ Microsoft\Data\Common\ConnectionString\AttestationProtocolUtilities.cs
+
+
+ Microsoft\Data\Common\ConnectionString\DbConnectionStringDefaults.cs
+
+
+ Microsoft\Data\Common\ConnectionString\DbConnectionStringKeywords.cs
+
+
+ Microsoft\Data\Common\ConnectionString\DbConnectionStringSynonyms.cs
+
+
+ Microsoft\Data\Common\ConnectionString\DbConnectionStringUtilities.cs
+
+
+ Microsoft\Data\Common\ConnectionString\IpAddressPreferenceUtilities.cs
+
+
+ Microsoft\Data\Common\ConnectionString\PoolBlockingUtilities.cs
Microsoft\Data\Common\DbConnectionOptions.Common.cs
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Common/DBConnectionString.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Common/DBConnectionString.cs
index 66c46602c5..4fe523ae2f 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Common/DBConnectionString.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Common/DBConnectionString.cs
@@ -2,16 +2,16 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Diagnostics;
+using System.Text;
+using Microsoft.Data.Common.ConnectionString;
+using Microsoft.Data.SqlClient;
+
namespace Microsoft.Data.Common
{
-
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Diagnostics;
- using System.Text;
- using Microsoft.Data.SqlClient;
-
[Serializable] // MDAC 83147
internal sealed class DBConnectionString
{
@@ -19,6 +19,7 @@ internal sealed class DBConnectionString
// used by permission classes so it is much easier to verify correctness
// when not worried about the class being modified during execution
+ // @TODO: Remove in favor of DbConnectionStringKeywords
private static class KEY
{
internal const string Password = DbConnectionStringKeywords.Password;
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Common/DbConnectionOptions.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Common/DbConnectionOptions.cs
index e240c3d822..b0507ea83e 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Common/DbConnectionOptions.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Common/DbConnectionOptions.cs
@@ -6,6 +6,7 @@
using System.Runtime.Versioning;
using System.Security;
using System.Text;
+using Microsoft.Data.Common.ConnectionString;
namespace Microsoft.Data.Common
{
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs
index c141793e1b..8a61bf7b8e 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs
@@ -388,22 +388,22 @@ public SqlConnection(string connectionString, SqlCredential credential) : this()
if (UsesActiveDirectoryManagedIdentity(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringBuilderUtil.ActiveDirectoryManagedIdentityString);
+ throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringUtilities.ActiveDirectoryManagedIdentityString);
}
if (UsesActiveDirectoryMSI(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringBuilderUtil.ActiveDirectoryMSIString);
+ throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringUtilities.ActiveDirectoryMSIString);
}
if (UsesActiveDirectoryDefault(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString);
+ throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringUtilities.ActiveDirectoryDefaultString);
}
if (UsesActiveDirectoryWorkloadIdentity(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringBuilderUtil.ActiveDirectoryWorkloadIdentityString);
+ throw SQL.SettingCredentialWithNonInteractiveArgument(DbConnectionStringUtilities.ActiveDirectoryWorkloadIdentityString);
}
Credential = credential;
@@ -823,19 +823,19 @@ override public string ConnectionString
}
else if (UsesActiveDirectoryManagedIdentity(connectionOptions))
{
- throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringBuilderUtil.ActiveDirectoryManagedIdentityString);
+ throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringUtilities.ActiveDirectoryManagedIdentityString);
}
else if (UsesActiveDirectoryMSI(connectionOptions))
{
- throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringBuilderUtil.ActiveDirectoryMSIString);
+ throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringUtilities.ActiveDirectoryMSIString);
}
else if (UsesActiveDirectoryDefault(connectionOptions))
{
- throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString);
+ throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringUtilities.ActiveDirectoryDefaultString);
}
else if (UsesActiveDirectoryWorkloadIdentity(connectionOptions))
{
- throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringBuilderUtil.ActiveDirectoryWorkloadIdentityString);
+ throw SQL.SettingNonInteractiveWithCredential(DbConnectionStringUtilities.ActiveDirectoryWorkloadIdentityString);
}
CheckAndThrowOnInvalidCombinationOfConnectionStringAndSqlCredential(connectionOptions);
@@ -1176,19 +1176,19 @@ public SqlCredential Credential
}
else if (UsesActiveDirectoryManagedIdentity(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringBuilderUtil.ActiveDirectoryManagedIdentityString);
+ throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringUtilities.ActiveDirectoryManagedIdentityString);
}
else if (UsesActiveDirectoryMSI(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringBuilderUtil.ActiveDirectoryMSIString);
+ throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringUtilities.ActiveDirectoryMSIString);
}
else if (UsesActiveDirectoryDefault(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString);
+ throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringUtilities.ActiveDirectoryDefaultString);
}
else if (UsesActiveDirectoryWorkloadIdentity(connectionOptions))
{
- throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringBuilderUtil.ActiveDirectoryWorkloadIdentityString);
+ throw SQL.SettingCredentialWithNonInteractiveInvalid(DbConnectionStringUtilities.ActiveDirectoryWorkloadIdentityString);
}
CheckAndThrowOnInvalidCombinationOfConnectionStringAndSqlCredential(connectionOptions);
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs
index f51723ace2..c8dcdd6934 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/AdapterUtil.cs
@@ -18,6 +18,7 @@
using System.Threading;
using System.Threading.Tasks;
using System.Transactions;
+using Microsoft.Data.Common.ConnectionString;
using Microsoft.Data.SqlClient;
using IsolationLevel = System.Data.IsolationLevel;
using Microsoft.Identity.Client;
@@ -47,6 +48,7 @@ internal static partial class ADP
{
// NOTE: Initializing a Task in SQL CLR requires the "UNSAFE" permission set (http://msdn.microsoft.com/en-us/library/ms172338.aspx)
// Therefore we are lazily initializing these Tasks to avoid forcing customers to use the "UNSAFE" set when they are actually using no Async features
+ // @TODO: These are not necessary because the TPL has optimized commonly used task return values like true and false.
private static Task s_trueTask;
internal static Task TrueTask => s_trueTask ??= Task.FromResult(true);
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/AttestationProtocolUtilities.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/AttestationProtocolUtilities.cs
new file mode 100644
index 0000000000..75e6eede3f
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/AttestationProtocolUtilities.cs
@@ -0,0 +1,148 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Diagnostics;
+using Microsoft.Data.SqlClient;
+
+namespace Microsoft.Data.Common.ConnectionString
+{
+ internal static class AttestationProtocolUtilities
+ {
+ ///
+ /// Convert a string value to the corresponding SqlConnectionAttestationProtocol
+ ///
+ ///
+ ///
+ ///
+ internal static bool TryConvertToAttestationProtocol(string value, out SqlConnectionAttestationProtocol result)
+ {
+ if (StringComparer.InvariantCultureIgnoreCase.Equals(value, nameof(SqlConnectionAttestationProtocol.HGS)))
+ {
+ result = SqlConnectionAttestationProtocol.HGS;
+ return true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, nameof(SqlConnectionAttestationProtocol.AAS)))
+ {
+ result = SqlConnectionAttestationProtocol.AAS;
+ return true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, nameof(SqlConnectionAttestationProtocol.None)))
+ {
+ result = SqlConnectionAttestationProtocol.None;
+ return true;
+ }
+ else
+ {
+ result = DbConnectionStringDefaults.AttestationProtocol;
+ return false;
+ }
+ }
+
+ internal static bool IsValidAttestationProtocol(SqlConnectionAttestationProtocol value)
+ {
+ Debug.Assert(Enum.GetNames(typeof(SqlConnectionAttestationProtocol)).Length == 4, "SqlConnectionAttestationProtocol enum has changed, update needed");
+ return value == SqlConnectionAttestationProtocol.NotSpecified
+ || value == SqlConnectionAttestationProtocol.HGS
+ || value == SqlConnectionAttestationProtocol.AAS
+ || value == SqlConnectionAttestationProtocol.None;
+ }
+
+ internal static string AttestationProtocolToString(SqlConnectionAttestationProtocol value)
+ {
+ Debug.Assert(IsValidAttestationProtocol(value), "value is not a valid attestation protocol");
+
+ return value switch
+ {
+ SqlConnectionAttestationProtocol.AAS => nameof(SqlConnectionAttestationProtocol.AAS),
+ SqlConnectionAttestationProtocol.HGS => nameof(SqlConnectionAttestationProtocol.HGS),
+ SqlConnectionAttestationProtocol.None => nameof(SqlConnectionAttestationProtocol.None),
+ _ => null
+ };
+ }
+
+ internal static SqlConnectionAttestationProtocol ConvertToAttestationProtocol(string keyword, object value)
+ {
+ if (value == null)
+ {
+ return DbConnectionStringDefaults.AttestationProtocol;
+ }
+
+ if (value is string sValue)
+ {
+ // try again after remove leading & trailing whitespaces.
+ sValue = sValue.Trim();
+ if (TryConvertToAttestationProtocol(sValue, out SqlConnectionAttestationProtocol result))
+ {
+ return result;
+ }
+
+ // string values must be valid
+ throw ADP.InvalidConnectionOptionValue(keyword);
+ }
+ else
+ {
+ // the value is not string, try other options
+ SqlConnectionAttestationProtocol eValue;
+
+ if (value is SqlConnectionAttestationProtocol protocol)
+ {
+ eValue = protocol;
+ }
+ else if (value.GetType().IsEnum)
+ {
+ // explicitly block scenarios in which user tries to use wrong enum types, like:
+ // builder["SqlConnectionAttestationProtocol"] = EnvironmentVariableTarget.Process;
+ // workaround: explicitly cast non-SqlConnectionAttestationProtocol enums to int
+ throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionAttestationProtocol), null);
+ }
+ else
+ {
+ try
+ {
+ // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
+ eValue = (SqlConnectionAttestationProtocol)Enum.ToObject(typeof(SqlConnectionAttestationProtocol), value);
+ }
+ catch (ArgumentException e)
+ {
+ // to be consistent with the messages we send in case of wrong type usage, replace
+ // the error with our exception, and keep the original one as inner one for troubleshooting
+ throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionAttestationProtocol), e);
+ }
+ }
+
+ if (IsValidAttestationProtocol(eValue))
+ {
+ return eValue;
+ }
+ else
+ {
+ throw ADP.InvalidEnumerationValue(typeof(SqlConnectionAttestationProtocol), (int)eValue);
+ }
+ }
+ }
+
+ internal static SqlConnectionEncryptOption ConvertToSqlConnectionEncryptOption(string keyword, object value)
+ {
+ if (value is null)
+ {
+ return DbConnectionStringDefaults.Encrypt;
+ }
+ else if(value is SqlConnectionEncryptOption eValue)
+ {
+ return eValue;
+ }
+ else if (value is string sValue)
+ {
+ return SqlConnectionEncryptOption.Parse(sValue);
+ }
+ else if(value is bool bValue)
+ {
+ return SqlConnectionEncryptOption.Parse(bValue);
+ }
+
+ throw ADP.InvalidConnectionOptionValue(keyword);
+ }
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringDefaults.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringDefaults.cs
new file mode 100644
index 0000000000..de3971a1e4
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringDefaults.cs
@@ -0,0 +1,64 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.Data.SqlClient;
+
+namespace Microsoft.Data.Common.ConnectionString
+{
+ internal static class DbConnectionStringDefaults
+ {
+ internal const ApplicationIntent ApplicationIntent = Microsoft.Data.SqlClient.ApplicationIntent.ReadWrite;
+ internal const string ApplicationName =
+ #if NETFRAMEWORK
+ "Framework Microsoft SqlClient Data Provider";
+ #else
+ "Core Microsoft SqlClient Data Provider";
+ #endif
+ internal const string AttachDBFilename = "";
+ internal const SqlConnectionAttestationProtocol AttestationProtocol = SqlConnectionAttestationProtocol.NotSpecified;
+ internal static readonly SqlAuthenticationMethod Authentication = SqlAuthenticationMethod.NotSpecified;
+ internal const SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled;
+ internal const int CommandTimeout = 30;
+ internal const int ConnectRetryCount = 1;
+ internal const int ConnectRetryInterval = 10;
+ internal const int ConnectTimeout = 15;
+ internal const bool ContextConnection = false;
+ internal const string CurrentLanguage = "";
+ internal const string DataSource = "";
+ internal const string EnclaveAttestationUrl = "";
+ internal static readonly SqlConnectionEncryptOption Encrypt = SqlConnectionEncryptOption.Mandatory;
+ internal const bool Enlist = true;
+ internal const string FailoverPartner = "";
+ internal const string FailoverPartnerSPN = "";
+ internal const string HostNameInCertificate = "";
+ internal const string InitialCatalog = "";
+ internal const bool IntegratedSecurity = false;
+ internal const SqlConnectionIPAddressPreference IPAddressPreference = SqlConnectionIPAddressPreference.IPv4First;
+ internal const int LoadBalanceTimeout = 0; // default of 0 means don't use
+ internal const int MaxPoolSize = 100;
+ internal const int MinPoolSize = 0;
+ internal const bool MultipleActiveResultSets = false;
+ internal const bool MultiSubnetFailover = false;
+ internal const int PacketSize = 8000;
+ internal const string Password = "";
+ internal const bool PersistSecurityInfo = false;
+ internal const PoolBlockingPeriod PoolBlockingPeriod = SqlClient.PoolBlockingPeriod.Auto;
+ internal const bool Pooling = true;
+ internal const bool Replication = false;
+ internal const string ServerCertificate = "";
+ internal const string ServerSPN = "";
+ internal const string TransactionBinding = "Implicit Unbind";
+ internal const bool TrustServerCertificate = false;
+ internal const string TypeSystemVersion = "Latest";
+ internal const string UserID = "";
+ internal const bool UserInstance = false;
+ internal const string WorkstationID = "";
+
+ #if NETFRAMEWORK
+ internal const bool ConnectionReset = true;
+ internal static readonly bool TransparentNetworkIPResolution = !LocalAppContextSwitches.DisableTNIRByDefault;
+ internal const string NetworkLibrary = "";
+ #endif
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringKeywords.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringKeywords.cs
new file mode 100644
index 0000000000..65cb781fa1
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringKeywords.cs
@@ -0,0 +1,72 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Microsoft.Data.Common.ConnectionString
+{
+ internal static class DbConnectionStringKeywords
+ {
+ // SqlClient
+ internal const string ApplicationIntent = "Application Intent";
+ internal const string ApplicationName = "Application Name";
+ internal const string AttachDBFilename = "AttachDbFilename";
+ internal const string AttestationProtocol = "Attestation Protocol";
+ internal const string Authentication = "Authentication";
+ internal const string ColumnEncryptionSetting = "Column Encryption Setting";
+ internal const string CommandTimeout = "Command Timeout";
+ internal const string ConnectionReset = "Connection Reset";
+ internal const string ConnectRetryCount = "Connect Retry Count";
+ internal const string ConnectRetryInterval = "Connect Retry Interval";
+ internal const string ConnectTimeout = "Connect Timeout";
+ internal const string ContextConnection = "Context Connection";
+ internal const string CurrentLanguage = "Current Language";
+ internal const string DataSource = "Data Source";
+ internal const string EnclaveAttestationUrl = "Enclave Attestation Url";
+ internal const string Encrypt = "Encrypt";
+ internal const string Enlist = "Enlist";
+ internal const string FailoverPartner = "Failover Partner";
+ internal const string FailoverPartnerSPN = "Failover Partner SPN";
+ internal const string HostNameInCertificate = "Host Name In Certificate";
+ internal const string InitialCatalog = "Initial Catalog";
+ internal const string IntegratedSecurity = "Integrated Security";
+ internal const string IPAddressPreference = "IP Address Preference";
+ internal const string LoadBalanceTimeout = "Load Balance Timeout";
+ internal const string MaxPoolSize = "Max Pool Size";
+ internal const string MinPoolSize = "Min Pool Size";
+ internal const string MultipleActiveResultSets = "Multiple Active Result Sets";
+ internal const string MultiSubnetFailover = "Multi Subnet Failover";
+ internal const string NetworkLibrary = "Network Library";
+ internal const string PacketSize = "Packet Size";
+ internal const string Password = "Password";
+ internal const string PersistSecurityInfo = "Persist Security Info";
+ internal const string PoolBlockingPeriod = "Pool Blocking Period";
+ internal const string Pooling = "Pooling";
+ internal const string Replication = "Replication";
+ internal const string ServerCertificate = "Server Certificate";
+ internal const string ServerSPN = "Server SPN";
+ internal const string TransactionBinding = "Transaction Binding";
+ internal const string TransparentNetworkIPResolution = "Transparent Network IP Resolution";
+ internal const string TrustServerCertificate = "Trust Server Certificate";
+ internal const string TypeSystemVersion = "Type System Version";
+ internal const string UserID = "User ID";
+ internal const string UserInstance = "User Instance";
+ internal const string WorkstationID = "Workstation ID";
+
+ #if NETFRAMEWORK
+ // Odbc
+ internal const string Driver = "Driver";
+ internal const string Dsn = "Dsn";
+ internal const string FileDsn = "FileDsn";
+ internal const string SaveFile = "SaveFile";
+
+ // OleDb
+ internal const string FileName = "File Name";
+ internal const string OleDbServices = "OLE DB Services";
+ internal const string Provider = "Provider";
+
+ // OracleClient
+ internal const string Unicode = "Unicode";
+ internal const string OmitOracleConnectionName = "Omit Oracle Connection Name";
+ #endif
+ }
+}
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
new file mode 100644
index 0000000000..f7d8881544
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringSynonyms.cs
@@ -0,0 +1,93 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace Microsoft.Data.Common.ConnectionString
+{
+ internal static class DbConnectionStringSynonyms
+ {
+ //internal const string TransparentNetworkIPResolution = TRANSPARENTNETWORKIPRESOLUTION;
+ internal const string TRANSPARENTNETWORKIPRESOLUTION = "transparentnetworkipresolution";
+
+ //internal const string ApplicationName = APP;
+ internal const string APP = "app";
+
+ // internal const string IPAddressPreference = IPADDRESSPREFERENCE;
+ internal const string IPADDRESSPREFERENCE = "ipaddresspreference";
+
+ //internal const string ApplicationIntent = APPLICATIONINTENT;
+ internal const string APPLICATIONINTENT = "applicationintent";
+
+ //internal const string AttachDBFilename = EXTENDEDPROPERTIES + "," + INITIALFILENAME;
+ internal const string EXTENDEDPROPERTIES = "extended properties";
+ internal const string INITIALFILENAME = "initial file name";
+
+ // internal const string HostNameInCertificate = HOSTNAMEINCERTIFICATE;
+ internal const string HOSTNAMEINCERTIFICATE = "hostnameincertificate";
+
+ // internal const string ServerCertificate = SERVERCERTIFICATE;
+ internal const string SERVERCERTIFICATE = "servercertificate";
+
+ //internal const string ConnectTimeout = CONNECTIONTIMEOUT + "," +TIMEOUT;
+ internal const string CONNECTIONTIMEOUT = "connection timeout";
+ internal const string TIMEOUT = "timeout";
+
+ //internal const string ConnectRetryCount = CONNECTRETRYCOUNT;
+ internal const string CONNECTRETRYCOUNT = "connectretrycount";
+
+ //internal const string ConnectRetryInterval = CONNECTRETRYINTERVAL;
+ internal const string CONNECTRETRYINTERVAL = "connectretryinterval";
+
+ //internal const string CurrentLanguage = LANGUAGE;
+ internal const string LANGUAGE = "language";
+
+ //internal const string OraDataSource = SERVER;
+ //internal const string SqlDataSource = ADDR + "," + ADDRESS + "," + SERVER + "," + NETWORKADDRESS;
+ internal const string ADDR = "addr";
+ internal const string ADDRESS = "address";
+ internal const string SERVER = "server";
+ internal const string NETWORKADDRESS = "network address";
+
+ //internal const string InitialCatalog = DATABASE;
+ internal const string DATABASE = "database";
+
+ //internal const string IntegratedSecurity = TRUSTEDCONNECTION;
+ internal const string TRUSTEDCONNECTION = "trusted_connection"; // underscore introduced in everett
+
+ //internal const string LoadBalanceTimeout = ConnectionLifetime;
+ internal const string ConnectionLifetime = "connection lifetime";
+
+ //internal const string MultipleActiveResultSets = MULTIPLEACTIVERESULTSETS;
+ internal const string MULTIPLEACTIVERESULTSETS = "multipleactiveresultsets";
+
+ //internal const string MultiSubnetFailover = MULTISUBNETFAILOVER;
+ internal const string MULTISUBNETFAILOVER = "multisubnetfailover";
+
+ //internal const string NetworkLibrary = NET + "," + NETWORK;
+ internal const string NET = "net";
+ internal const string NETWORK = "network";
+
+ //internal const string PoolBlockingPeriod = POOLBLOCKINGPERIOD;
+ internal const string POOLBLOCKINGPERIOD = "poolblockingperiod";
+
+ //internal const string Password = Pwd;
+ internal const string Pwd = "pwd";
+
+ //internal const string PersistSecurityInfo = PERSISTSECURITYINFO;
+ internal const string PERSISTSECURITYINFO = "persistsecurityinfo";
+
+ //internal const string TrustServerCertificate = TRUSTSERVERCERTIFICATE;
+ internal const string TRUSTSERVERCERTIFICATE = "trustservercertificate";
+
+ //internal const string UserID = UID + "," + User;
+ internal const string UID = "uid";
+ internal const string User = "user";
+
+ //internal const string WorkstationID = WSID;
+ internal const string WSID = "wsid";
+
+ //internal const string server SPNs
+ internal const string ServerSPN = "ServerSPN";
+ internal const string FailoverPartnerSPN = "FailoverPartnerSPN";
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringUtilities.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringUtilities.cs
new file mode 100644
index 0000000000..927b2e62a6
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/DbConnectionStringUtilities.cs
@@ -0,0 +1,592 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using Microsoft.Data.Common.ConnectionString;
+using Microsoft.Data.SqlClient;
+
+namespace Microsoft.Data.Common
+{
+ internal static class DbConnectionStringUtilities
+ {
+ internal static bool ConvertToBoolean(object value)
+ {
+ Debug.Assert(value != null, "ConvertToBoolean(null)");
+ if (value is string svalue)
+ {
+ if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes"))
+ {
+ return true;
+ }
+ else if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "false") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "no"))
+ {
+ return false;
+ }
+ else
+ {
+ string tmp = svalue.Trim(); // Remove leading & trailing white space.
+ if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "true") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "yes"))
+ {
+ return true;
+ }
+ else if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "false") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "no"))
+ {
+ return false;
+ }
+ }
+ return bool.Parse(svalue);
+ }
+ try
+ {
+ return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
+ }
+ catch (InvalidCastException e)
+ {
+ throw ADP.ConvertFailed(value.GetType(), typeof(bool), e);
+ }
+ }
+
+ internal static bool ConvertToIntegratedSecurity(object value)
+ {
+ Debug.Assert(value != null, "ConvertToIntegratedSecurity(null)");
+ if (value is string svalue)
+ {
+ if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "sspi") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes"))
+ return true;
+ else if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "false") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "no"))
+ return false;
+ else
+ {
+ string tmp = svalue.Trim(); // Remove leading & trailing white space.
+ if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "sspi") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "true") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "yes"))
+ return true;
+ else if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "false") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "no"))
+ return false;
+ }
+ return bool.Parse(svalue);
+ }
+ try
+ {
+ return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
+ }
+ catch (InvalidCastException e)
+ {
+ throw ADP.ConvertFailed(value.GetType(), typeof(bool), e);
+ }
+ }
+
+ internal static int ConvertToInt32(object value)
+ {
+ try
+ {
+ return Convert.ToInt32(value, CultureInfo.InvariantCulture);
+ }
+ catch (InvalidCastException e)
+ {
+ throw ADP.ConvertFailed(value.GetType(), typeof(int), e);
+ }
+ }
+
+ internal static string ConvertToString(object value)
+ {
+ try
+ {
+ return Convert.ToString(value, CultureInfo.InvariantCulture);
+ }
+ catch (InvalidCastException e)
+ {
+ throw ADP.ConvertFailed(value.GetType(), typeof(string), e);
+ }
+ }
+
+ internal static bool TryConvertToApplicationIntent(string value, out ApplicationIntent result)
+ {
+ Debug.Assert(Enum.GetNames(typeof(ApplicationIntent)).Length == 2, "ApplicationIntent enum has changed, update needed");
+ Debug.Assert(value != null, "TryConvertToApplicationIntent(null,...)");
+
+ if (StringComparer.OrdinalIgnoreCase.Equals(value, nameof(ApplicationIntent.ReadOnly)))
+ {
+ result = ApplicationIntent.ReadOnly;
+ return true;
+ }
+ else if (StringComparer.OrdinalIgnoreCase.Equals(value, nameof(ApplicationIntent.ReadWrite)))
+ {
+ result = ApplicationIntent.ReadWrite;
+ return true;
+ }
+ else
+ {
+ result = DbConnectionStringDefaults.ApplicationIntent;
+ return false;
+ }
+ }
+
+ internal static bool IsValidApplicationIntentValue(ApplicationIntent value)
+ {
+ Debug.Assert(Enum.GetNames(typeof(ApplicationIntent)).Length == 2, "ApplicationIntent enum has changed, update needed");
+ return value == ApplicationIntent.ReadOnly || value == ApplicationIntent.ReadWrite;
+ }
+
+ internal static string ApplicationIntentToString(ApplicationIntent value)
+ {
+ Debug.Assert(IsValidApplicationIntentValue(value));
+ if (value == ApplicationIntent.ReadOnly)
+ {
+ return nameof(ApplicationIntent.ReadOnly);
+ }
+ else
+ {
+ return nameof(ApplicationIntent.ReadWrite);
+ }
+ }
+
+ ///
+ /// This method attempts to convert the given value tp ApplicationIntent enum. The algorithm is:
+ /// * if the value is from type string, it will be matched against ApplicationIntent enum names only, using ordinal, case-insensitive comparer
+ /// * if the value is from type ApplicationIntent, it will be used as is
+ /// * if the value is from integral type (SByte, Int16, Int32, Int64, Byte, UInt16, UInt32, or UInt64), it will be converted to enum
+ /// * if the value is another enum or any other type, it will be blocked with an appropriate ArgumentException
+ ///
+ /// in any case above, if the converted value is out of valid range, the method raises ArgumentOutOfRangeException.
+ ///
+ /// application intent value in the valid range
+ internal static ApplicationIntent ConvertToApplicationIntent(string keyword, object value)
+ {
+ Debug.Assert(value != null, "ConvertToApplicationIntent(null)");
+ if (value is string sValue)
+ {
+ // We could use Enum.TryParse here, but it accepts value combinations like
+ // "ReadOnly, ReadWrite" which are unwelcome here
+ // Also, Enum.TryParse is 100x slower than plain StringComparer.OrdinalIgnoreCase.Equals method.
+
+ if (TryConvertToApplicationIntent(sValue, out ApplicationIntent result))
+ {
+ return result;
+ }
+
+ // try again after remove leading & trailing whitespaces.
+ sValue = sValue.Trim();
+ if (TryConvertToApplicationIntent(sValue, out result))
+ {
+ return result;
+ }
+
+ // string values must be valid
+ throw ADP.InvalidConnectionOptionValue(keyword);
+ }
+ else
+ {
+ // the value is not string, try other options
+ ApplicationIntent eValue;
+
+ if (value is ApplicationIntent intent)
+ {
+ // quick path for the most common case
+ eValue = intent;
+ }
+ else if (value.GetType().IsEnum)
+ {
+ // explicitly block scenarios in which user tries to use wrong enum types, like:
+ // builder["ApplicationIntent"] = EnvironmentVariableTarget.Process;
+ // workaround: explicitly cast non-ApplicationIntent enums to int
+ throw ADP.ConvertFailed(value.GetType(), typeof(ApplicationIntent), null);
+ }
+ else
+ {
+ try
+ {
+ // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
+ eValue = (ApplicationIntent)Enum.ToObject(typeof(ApplicationIntent), value);
+ }
+ catch (ArgumentException e)
+ {
+ // to be consistent with the messages we send in case of wrong type usage, replace
+ // the error with our exception, and keep the original one as inner one for troubleshooting
+ throw ADP.ConvertFailed(value.GetType(), typeof(ApplicationIntent), e);
+ }
+ }
+
+ // ensure value is in valid range
+ if (IsValidApplicationIntentValue(eValue))
+ {
+ return eValue;
+ }
+ else
+ {
+ throw ADP.InvalidEnumerationValue(typeof(ApplicationIntent), (int)eValue);
+ }
+ }
+ }
+
+ const string SqlPasswordString = "Sql Password";
+ [Obsolete("ActiveDirectoryPassword is deprecated.")]
+ const string ActiveDirectoryPasswordString = "Active Directory Password";
+ const string ActiveDirectoryIntegratedString = "Active Directory Integrated";
+ const string ActiveDirectoryInteractiveString = "Active Directory Interactive";
+ const string ActiveDirectoryServicePrincipalString = "Active Directory Service Principal";
+ const string ActiveDirectoryDeviceCodeFlowString = "Active Directory Device Code Flow";
+ internal const string ActiveDirectoryManagedIdentityString = "Active Directory Managed Identity";
+ internal const string ActiveDirectoryMSIString = "Active Directory MSI";
+ internal const string ActiveDirectoryDefaultString = "Active Directory Default";
+ internal const string ActiveDirectoryWorkloadIdentityString = "Active Directory Workload Identity";
+
+#if DEBUG
+ private static readonly string[] s_supportedAuthenticationModes =
+ {
+ "NotSpecified",
+ "SqlPassword",
+ "ActiveDirectoryPassword",
+ "ActiveDirectoryIntegrated",
+ "ActiveDirectoryInteractive",
+ "ActiveDirectoryServicePrincipal",
+ "ActiveDirectoryDeviceCodeFlow",
+ "ActiveDirectoryManagedIdentity",
+ "ActiveDirectoryMSI",
+ "ActiveDirectoryDefault",
+ "ActiveDirectoryWorkloadIdentity",
+ };
+
+ private static bool IsValidAuthenticationMethodEnum()
+ {
+ string[] names = Enum.GetNames(typeof(SqlAuthenticationMethod));
+ int l = s_supportedAuthenticationModes.Length;
+ bool listValid;
+ if (listValid = names.Length == l)
+ {
+ for (int i = 0; i < l; i++)
+ {
+ if (string.Compare(s_supportedAuthenticationModes[i], names[i], StringComparison.Ordinal) != 0)
+ {
+ listValid = false;
+ }
+ }
+ }
+ return listValid;
+ }
+#endif
+
+ internal static bool TryConvertToAuthenticationType(string value, out SqlAuthenticationMethod result)
+ {
+#if DEBUG
+ Debug.Assert(IsValidAuthenticationMethodEnum(), "SqlAuthenticationMethod enum has changed, update needed");
+#endif
+ bool isSuccess = false;
+
+ if (StringComparer.InvariantCultureIgnoreCase.Equals(value, SqlPasswordString)
+ || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.SqlPassword, CultureInfo.InvariantCulture)))
+ {
+ result = SqlAuthenticationMethod.SqlPassword;
+ isSuccess = true;
+ }
+ #pragma warning disable 0618
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryPasswordString)
+ || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryPassword, CultureInfo.InvariantCulture)))
+ {
+ result = SqlAuthenticationMethod.ActiveDirectoryPassword;
+ #pragma warning restore 0618
+ isSuccess = true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryIntegratedString)
+ || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryIntegrated, CultureInfo.InvariantCulture)))
+ {
+ result = SqlAuthenticationMethod.ActiveDirectoryIntegrated;
+ isSuccess = true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryInteractiveString)
+ || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryInteractive, CultureInfo.InvariantCulture)))
+ {
+ result = SqlAuthenticationMethod.ActiveDirectoryInteractive;
+ isSuccess = true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryServicePrincipalString)
+ || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryServicePrincipal, CultureInfo.InvariantCulture)))
+ {
+ result = SqlAuthenticationMethod.ActiveDirectoryServicePrincipal;
+ isSuccess = true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryDeviceCodeFlowString)
+ || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow, CultureInfo.InvariantCulture)))
+ {
+ result = SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow;
+ isSuccess = true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryManagedIdentityString)
+ || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryManagedIdentity, CultureInfo.InvariantCulture)))
+ {
+ result = SqlAuthenticationMethod.ActiveDirectoryManagedIdentity;
+ isSuccess = true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryMSIString)
+ || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryMSI, CultureInfo.InvariantCulture)))
+ {
+ result = SqlAuthenticationMethod.ActiveDirectoryMSI;
+ isSuccess = true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryDefaultString)
+ || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryDefault, CultureInfo.InvariantCulture)))
+ {
+ result = SqlAuthenticationMethod.ActiveDirectoryDefault;
+ isSuccess = true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryWorkloadIdentityString)
+ || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity, CultureInfo.InvariantCulture)))
+ {
+ result = SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity;
+ isSuccess = true;
+ }
+ else
+ {
+ result = DbConnectionStringDefaults.Authentication;
+ }
+ return isSuccess;
+ }
+
+ ///
+ /// Convert a string value to the corresponding SqlConnectionColumnEncryptionSetting.
+ ///
+ ///
+ ///
+ ///
+ internal static bool TryConvertToColumnEncryptionSetting(string value, out SqlConnectionColumnEncryptionSetting result)
+ {
+ bool isSuccess = false;
+
+ if (StringComparer.InvariantCultureIgnoreCase.Equals(value, nameof(SqlConnectionColumnEncryptionSetting.Enabled)))
+ {
+ result = SqlConnectionColumnEncryptionSetting.Enabled;
+ isSuccess = true;
+ }
+ else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, nameof(SqlConnectionColumnEncryptionSetting.Disabled)))
+ {
+ result = SqlConnectionColumnEncryptionSetting.Disabled;
+ isSuccess = true;
+ }
+ else
+ {
+ result = DbConnectionStringDefaults.ColumnEncryptionSetting;
+ }
+
+ return isSuccess;
+ }
+
+ ///
+ /// Is it a valid connection level column encryption setting ?
+ ///
+ ///
+ ///
+ internal static bool IsValidColumnEncryptionSetting(SqlConnectionColumnEncryptionSetting value)
+ {
+ Debug.Assert(Enum.GetNames(typeof(SqlConnectionColumnEncryptionSetting)).Length == 2, "SqlConnectionColumnEncryptionSetting enum has changed, update needed");
+ return value == SqlConnectionColumnEncryptionSetting.Enabled || value == SqlConnectionColumnEncryptionSetting.Disabled;
+ }
+
+ ///
+ /// Convert connection level column encryption setting value to string.
+ ///
+ ///
+ ///
+ internal static string ColumnEncryptionSettingToString(SqlConnectionColumnEncryptionSetting value)
+ {
+ Debug.Assert(IsValidColumnEncryptionSetting(value), "value is not a valid connection level column encryption setting.");
+
+ return value switch
+ {
+ SqlConnectionColumnEncryptionSetting.Enabled => nameof(SqlConnectionColumnEncryptionSetting.Enabled),
+ SqlConnectionColumnEncryptionSetting.Disabled => nameof(SqlConnectionColumnEncryptionSetting.Disabled),
+ _ => null,
+ };
+ }
+
+ internal static bool IsValidAuthenticationTypeValue(SqlAuthenticationMethod value)
+ {
+ Debug.Assert(Enum.GetNames(typeof(SqlAuthenticationMethod)).Length == 11, "SqlAuthenticationMethod enum has changed, update needed");
+ return value == SqlAuthenticationMethod.SqlPassword
+ #pragma warning disable 0618
+ || value == SqlAuthenticationMethod.ActiveDirectoryPassword
+ #pragma warning restore 0618
+ || value == SqlAuthenticationMethod.ActiveDirectoryIntegrated
+ || value == SqlAuthenticationMethod.ActiveDirectoryInteractive
+ || value == SqlAuthenticationMethod.ActiveDirectoryServicePrincipal
+ || value == SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow
+ || value == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity
+ || value == SqlAuthenticationMethod.ActiveDirectoryMSI
+ || value == SqlAuthenticationMethod.ActiveDirectoryDefault
+ || value == SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity
+ || value == SqlAuthenticationMethod.NotSpecified;
+ }
+
+ internal static string AuthenticationTypeToString(SqlAuthenticationMethod value)
+ {
+ Debug.Assert(IsValidAuthenticationTypeValue(value));
+
+ return value switch
+ {
+ SqlAuthenticationMethod.SqlPassword => SqlPasswordString,
+ #pragma warning disable 0618
+ SqlAuthenticationMethod.ActiveDirectoryPassword => ActiveDirectoryPasswordString,
+ #pragma warning restore 0618
+ SqlAuthenticationMethod.ActiveDirectoryIntegrated => ActiveDirectoryIntegratedString,
+ SqlAuthenticationMethod.ActiveDirectoryInteractive => ActiveDirectoryInteractiveString,
+ SqlAuthenticationMethod.ActiveDirectoryServicePrincipal => ActiveDirectoryServicePrincipalString,
+ SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow => ActiveDirectoryDeviceCodeFlowString,
+ SqlAuthenticationMethod.ActiveDirectoryManagedIdentity => ActiveDirectoryManagedIdentityString,
+ SqlAuthenticationMethod.ActiveDirectoryMSI => ActiveDirectoryMSIString,
+ SqlAuthenticationMethod.ActiveDirectoryDefault => ActiveDirectoryDefaultString,
+ SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity => ActiveDirectoryWorkloadIdentityString,
+ _ => null
+ };
+ }
+
+ internal static SqlAuthenticationMethod ConvertToAuthenticationType(string keyword, object value)
+ {
+ if (value == null)
+ {
+ return DbConnectionStringDefaults.Authentication;
+ }
+
+ if (value is string sValue)
+ {
+ if (TryConvertToAuthenticationType(sValue, out SqlAuthenticationMethod result))
+ {
+ return result;
+ }
+
+ // try again after remove leading & trailing whitespaces.
+ sValue = sValue.Trim();
+ if (TryConvertToAuthenticationType(sValue, out result))
+ {
+ return result;
+ }
+
+ // string values must be valid
+ throw ADP.InvalidConnectionOptionValue(keyword);
+ }
+ else
+ {
+ // the value is not string, try other options
+ SqlAuthenticationMethod eValue;
+
+ if (value is SqlAuthenticationMethod method)
+ {
+ // quick path for the most common case
+ eValue = method;
+ }
+ else if (value.GetType().IsEnum)
+ {
+ // explicitly block scenarios in which user tries to use wrong enum types, like:
+ // builder["ApplicationIntent"] = EnvironmentVariableTarget.Process;
+ // workaround: explicitly cast non-ApplicationIntent enums to int
+ throw ADP.ConvertFailed(value.GetType(), typeof(SqlAuthenticationMethod), null);
+ }
+ else
+ {
+ try
+ {
+ // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
+ eValue = (SqlAuthenticationMethod)Enum.ToObject(typeof(SqlAuthenticationMethod), value);
+ }
+ catch (ArgumentException e)
+ {
+ // to be consistent with the messages we send in case of wrong type usage, replace
+ // the error with our exception, and keep the original one as inner one for troubleshooting
+ throw ADP.ConvertFailed(value.GetType(), typeof(SqlAuthenticationMethod), e);
+ }
+ }
+
+ // ensure value is in valid range
+ if (IsValidAuthenticationTypeValue(eValue))
+ {
+ return eValue;
+ }
+ else
+ {
+ throw ADP.InvalidEnumerationValue(typeof(SqlAuthenticationMethod), (int)eValue);
+ }
+ }
+ }
+
+ ///
+ /// Convert the provided value to a SqlConnectionColumnEncryptionSetting.
+ ///
+ ///
+ ///
+ ///
+ internal static SqlConnectionColumnEncryptionSetting ConvertToColumnEncryptionSetting(string keyword, object value)
+ {
+ if (value == null)
+ {
+ return DbConnectionStringDefaults.ColumnEncryptionSetting;
+ }
+
+ if (value is string sValue)
+ {
+ if (TryConvertToColumnEncryptionSetting(sValue, out SqlConnectionColumnEncryptionSetting result))
+ {
+ return result;
+ }
+
+ // try again after remove leading & trailing whitespaces.
+ sValue = sValue.Trim();
+ if (TryConvertToColumnEncryptionSetting(sValue, out result))
+ {
+ return result;
+ }
+
+ // string values must be valid
+ throw ADP.InvalidConnectionOptionValue(keyword);
+ }
+ else
+ {
+ // the value is not string, try other options
+ SqlConnectionColumnEncryptionSetting eValue;
+
+ if (value is SqlConnectionColumnEncryptionSetting setting)
+ {
+ // quick path for the most common case
+ eValue = setting;
+ }
+ else if (value.GetType().IsEnum)
+ {
+ // explicitly block scenarios in which user tries to use wrong enum types, like:
+ // builder["SqlConnectionColumnEncryptionSetting"] = EnvironmentVariableTarget.Process;
+ // workaround: explicitly cast non-SqlConnectionColumnEncryptionSetting enums to int
+ throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionColumnEncryptionSetting), null);
+ }
+ else
+ {
+ try
+ {
+ // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
+ eValue = (SqlConnectionColumnEncryptionSetting)Enum.ToObject(typeof(SqlConnectionColumnEncryptionSetting), value);
+ }
+ catch (ArgumentException e)
+ {
+ // to be consistent with the messages we send in case of wrong type usage, replace
+ // the error with our exception, and keep the original one as inner one for troubleshooting
+ throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionColumnEncryptionSetting), e);
+ }
+ }
+
+ // ensure value is in valid range
+ if (IsValidColumnEncryptionSetting(eValue))
+ {
+ return eValue;
+ }
+ else
+ {
+ throw ADP.InvalidEnumerationValue(typeof(SqlConnectionColumnEncryptionSetting), (int)eValue);
+ }
+ }
+ }
+ }
+
+
+
+
+
+
+}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/IpAddressPreferenceUtilities.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/IpAddressPreferenceUtilities.cs
new file mode 100644
index 0000000000..a9e59dfe2b
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/IpAddressPreferenceUtilities.cs
@@ -0,0 +1,115 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Collections.Generic;
+using Microsoft.Data.SqlClient;
+
+namespace Microsoft.Data.Common.ConnectionString
+{
+ internal static class IpAddressPreferenceUtilities
+ {
+ ///
+ /// IP Address Preference.
+ ///
+ private readonly static Dictionary s_preferenceNames = new(StringComparer.InvariantCultureIgnoreCase);
+
+ static IpAddressPreferenceUtilities()
+ {
+ foreach (SqlConnectionIPAddressPreference item in Enum.GetValues(typeof(SqlConnectionIPAddressPreference)))
+ {
+ s_preferenceNames.Add(item.ToString(), item);
+ }
+ }
+
+ ///
+ /// Convert a string value to the corresponding IPAddressPreference.
+ ///
+ /// The string representation of the enumeration name to convert.
+ /// When this method returns, `result` contains an object of type `SqlConnectionIPAddressPreference` whose value is represented by `value` if the operation succeeds.
+ /// If the parse operation fails, `result` contains the default value of the `SqlConnectionIPAddressPreference` type.
+ /// `true` if the value parameter was converted successfully; otherwise, `false`.
+ internal static bool TryConvertToIPAddressPreference(string value, out SqlConnectionIPAddressPreference result)
+ {
+ if (!s_preferenceNames.TryGetValue(value, out result))
+ {
+ result = DbConnectionStringDefaults.IPAddressPreference;
+ return false;
+ }
+ return true;
+ }
+
+ ///
+ /// Verifies if the `value` is defined in the expected Enum.
+ ///
+ internal static bool IsValidIPAddressPreference(SqlConnectionIPAddressPreference value)
+ => value == SqlConnectionIPAddressPreference.IPv4First
+ || value == SqlConnectionIPAddressPreference.IPv6First
+ || value == SqlConnectionIPAddressPreference.UsePlatformDefault;
+
+ internal static string IPAddressPreferenceToString(SqlConnectionIPAddressPreference value)
+ => Enum.GetName(typeof(SqlConnectionIPAddressPreference), value);
+
+ internal static SqlConnectionIPAddressPreference ConvertToIPAddressPreference(string keyword, object value)
+ {
+ if (value is null)
+ {
+ return DbConnectionStringDefaults.IPAddressPreference; // IPv4First
+ }
+
+ if (value is string sValue)
+ {
+ // try again after remove leading & trailing whitespaces.
+ sValue = sValue.Trim();
+ if (TryConvertToIPAddressPreference(sValue, out SqlConnectionIPAddressPreference result))
+ {
+ return result;
+ }
+
+ // string values must be valid
+ throw ADP.InvalidConnectionOptionValue(keyword);
+ }
+ else
+ {
+ // the value is not string, try other options
+ SqlConnectionIPAddressPreference eValue;
+
+ if (value is SqlConnectionIPAddressPreference preference)
+ {
+ eValue = preference;
+ }
+ else if (value.GetType().IsEnum)
+ {
+ // explicitly block scenarios in which user tries to use wrong enum types, like:
+ // builder["SqlConnectionIPAddressPreference"] = EnvironmentVariableTarget.Process;
+ // workaround: explicitly cast non-SqlConnectionIPAddressPreference enums to int
+ throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionIPAddressPreference), null);
+ }
+ else
+ {
+ try
+ {
+ // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
+ eValue = (SqlConnectionIPAddressPreference)Enum.ToObject(typeof(SqlConnectionIPAddressPreference), value);
+ }
+ catch (ArgumentException e)
+ {
+ // to be consistent with the messages we send in case of wrong type usage, replace
+ // the error with our exception, and keep the original one as inner one for troubleshooting
+ throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionIPAddressPreference), e);
+ }
+ }
+
+ if (IsValidIPAddressPreference(eValue))
+ {
+ return eValue;
+ }
+ else
+ {
+ throw ADP.InvalidEnumerationValue(typeof(SqlConnectionIPAddressPreference), (int)eValue);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/PoolBlockingUtilities.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/PoolBlockingUtilities.cs
new file mode 100644
index 0000000000..3a69271317
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/ConnectionString/PoolBlockingUtilities.cs
@@ -0,0 +1,136 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Diagnostics;
+using Microsoft.Data.SqlClient;
+
+namespace Microsoft.Data.Common.ConnectionString
+{
+ internal static class PoolBlockingUtilities
+ {
+ internal static bool TryConvertToPoolBlockingPeriod(string value, out PoolBlockingPeriod result)
+ {
+ Debug.Assert(Enum.GetNames(typeof(PoolBlockingPeriod)).Length == 3, "PoolBlockingPeriod enum has changed, update needed");
+ Debug.Assert(value != null, "TryConvertToPoolBlockingPeriod(null,...)");
+
+ if (StringComparer.OrdinalIgnoreCase.Equals(value, nameof(PoolBlockingPeriod.Auto)))
+ {
+ result = PoolBlockingPeriod.Auto;
+ return true;
+ }
+ else if (StringComparer.OrdinalIgnoreCase.Equals(value, nameof(PoolBlockingPeriod.AlwaysBlock)))
+ {
+ result = PoolBlockingPeriod.AlwaysBlock;
+ return true;
+ }
+ else if (StringComparer.OrdinalIgnoreCase.Equals(value, nameof(PoolBlockingPeriod.NeverBlock)))
+ {
+ result = PoolBlockingPeriod.NeverBlock;
+ return true;
+ }
+ else
+ {
+ result = DbConnectionStringDefaults.PoolBlockingPeriod;
+ return false;
+ }
+ }
+
+ internal static bool IsValidPoolBlockingPeriodValue(PoolBlockingPeriod value)
+ {
+ Debug.Assert(Enum.GetNames(typeof(PoolBlockingPeriod)).Length == 3, "PoolBlockingPeriod enum has changed, update needed");
+ return value == PoolBlockingPeriod.Auto || value == PoolBlockingPeriod.AlwaysBlock || value == PoolBlockingPeriod.NeverBlock;
+ }
+
+ internal static string PoolBlockingPeriodToString(PoolBlockingPeriod value)
+ {
+ Debug.Assert(IsValidPoolBlockingPeriodValue(value));
+
+ return value switch
+ {
+ PoolBlockingPeriod.AlwaysBlock => nameof(PoolBlockingPeriod.AlwaysBlock),
+ PoolBlockingPeriod.NeverBlock => nameof(PoolBlockingPeriod.NeverBlock),
+ _ => nameof(PoolBlockingPeriod.Auto),
+ };
+ }
+
+ ///
+ /// This method attempts to convert the given value to a PoolBlockingPeriod enum. The algorithm is:
+ /// * if the value is from type string, it will be matched against PoolBlockingPeriod enum names only, using ordinal, case-insensitive comparer
+ /// * if the value is from type PoolBlockingPeriod, it will be used as is
+ /// * if the value is from integral type (SByte, Int16, Int32, Int64, Byte, UInt16, UInt32, or UInt64), it will be converted to enum
+ /// * if the value is another enum or any other type, it will be blocked with an appropriate ArgumentException
+ ///
+ /// in any case above, if the converted value is out of valid range, the method raises ArgumentOutOfRangeException.
+ ///
+ /// PoolBlockingPeriod value in the valid range
+ internal static PoolBlockingPeriod ConvertToPoolBlockingPeriod(string keyword, object value)
+ {
+ Debug.Assert(value != null, "ConvertToPoolBlockingPeriod(null)");
+ if (value is string sValue)
+ {
+ // We could use Enum.TryParse here, but it accepts value combinations like
+ // "ReadOnly, ReadWrite" which are unwelcome here
+ // Also, Enum.TryParse is 100x slower than plain StringComparer.OrdinalIgnoreCase.Equals method.
+
+ if (TryConvertToPoolBlockingPeriod(sValue, out PoolBlockingPeriod result))
+ {
+ return result;
+ }
+
+ // try again after remove leading & trailing whitespaces.
+ sValue = sValue.Trim();
+ if (TryConvertToPoolBlockingPeriod(sValue, out result))
+ {
+ return result;
+ }
+
+ // string values must be valid
+ throw ADP.InvalidConnectionOptionValue(keyword);
+ }
+ else
+ {
+ // the value is not string, try other options
+ PoolBlockingPeriod eValue;
+
+ if (value is PoolBlockingPeriod period)
+ {
+ // quick path for the most common case
+ eValue = period;
+ }
+ else if (value.GetType().IsEnum)
+ {
+ // explicitly block scenarios in which user tries to use wrong enum types, like:
+ // builder["PoolBlockingPeriod"] = EnvironmentVariableTarget.Process;
+ // workaround: explicitly cast non-PoolBlockingPeriod enums to int
+ throw ADP.ConvertFailed(value.GetType(), typeof(PoolBlockingPeriod), null);
+ }
+ else
+ {
+ try
+ {
+ // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
+ eValue = (PoolBlockingPeriod)Enum.ToObject(typeof(PoolBlockingPeriod), value);
+ }
+ catch (ArgumentException e)
+ {
+ // to be consistent with the messages we send in case of wrong type usage, replace
+ // the error with our exception, and keep the original one as inner one for troubleshooting
+ throw ADP.ConvertFailed(value.GetType(), typeof(PoolBlockingPeriod), e);
+ }
+ }
+
+ // ensure value is in valid range
+ if (IsValidPoolBlockingPeriodValue(eValue))
+ {
+ return eValue;
+ }
+ else
+ {
+ throw ADP.InvalidEnumerationValue(typeof(ApplicationIntent), (int)eValue);
+ }
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionOptions.Common.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionOptions.Common.cs
index f72eb5ee59..f9e83b0120 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionOptions.Common.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionOptions.Common.cs
@@ -8,6 +8,7 @@
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
+using Microsoft.Data.Common.ConnectionString;
using Microsoft.Data.SqlClient;
namespace Microsoft.Data.Common
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs
deleted file mode 100644
index 61c189e738..0000000000
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs
+++ /dev/null
@@ -1,1157 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using Microsoft.Data.SqlClient;
-
-namespace Microsoft.Data.Common
-{
- internal static class DbConnectionStringBuilderUtil
- {
- internal static bool ConvertToBoolean(object value)
- {
- Debug.Assert(value != null, "ConvertToBoolean(null)");
- if (value is string svalue)
- {
- if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes"))
- {
- return true;
- }
- else if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "false") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "no"))
- {
- return false;
- }
- else
- {
- string tmp = svalue.Trim(); // Remove leading & trailing white space.
- if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "true") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "yes"))
- {
- return true;
- }
- else if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "false") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "no"))
- {
- return false;
- }
- }
- return bool.Parse(svalue);
- }
- try
- {
- return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
- }
- catch (InvalidCastException e)
- {
- throw ADP.ConvertFailed(value.GetType(), typeof(bool), e);
- }
- }
-
- internal static bool ConvertToIntegratedSecurity(object value)
- {
- Debug.Assert(value != null, "ConvertToIntegratedSecurity(null)");
- if (value is string svalue)
- {
- if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "sspi") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes"))
- return true;
- else if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "false") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "no"))
- return false;
- else
- {
- string tmp = svalue.Trim(); // Remove leading & trailing white space.
- if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "sspi") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "true") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "yes"))
- return true;
- else if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "false") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "no"))
- return false;
- }
- return bool.Parse(svalue);
- }
- try
- {
- return Convert.ToBoolean(value, CultureInfo.InvariantCulture);
- }
- catch (InvalidCastException e)
- {
- throw ADP.ConvertFailed(value.GetType(), typeof(bool), e);
- }
- }
-
- internal static int ConvertToInt32(object value)
- {
- try
- {
- return Convert.ToInt32(value, CultureInfo.InvariantCulture);
- }
- catch (InvalidCastException e)
- {
- throw ADP.ConvertFailed(value.GetType(), typeof(int), e);
- }
- }
-
- internal static string ConvertToString(object value)
- {
- try
- {
- return Convert.ToString(value, CultureInfo.InvariantCulture);
- }
- catch (InvalidCastException e)
- {
- throw ADP.ConvertFailed(value.GetType(), typeof(string), e);
- }
- }
-
- #region <>
- internal static bool TryConvertToPoolBlockingPeriod(string value, out PoolBlockingPeriod result)
- {
- Debug.Assert(Enum.GetNames(typeof(PoolBlockingPeriod)).Length == 3, "PoolBlockingPeriod enum has changed, update needed");
- Debug.Assert(value != null, "TryConvertToPoolBlockingPeriod(null,...)");
-
- if (StringComparer.OrdinalIgnoreCase.Equals(value, nameof(PoolBlockingPeriod.Auto)))
- {
- result = PoolBlockingPeriod.Auto;
- return true;
- }
- else if (StringComparer.OrdinalIgnoreCase.Equals(value, nameof(PoolBlockingPeriod.AlwaysBlock)))
- {
- result = PoolBlockingPeriod.AlwaysBlock;
- return true;
- }
- else if (StringComparer.OrdinalIgnoreCase.Equals(value, nameof(PoolBlockingPeriod.NeverBlock)))
- {
- result = PoolBlockingPeriod.NeverBlock;
- return true;
- }
- else
- {
- result = DbConnectionStringDefaults.PoolBlockingPeriod;
- return false;
- }
- }
-
- internal static bool IsValidPoolBlockingPeriodValue(PoolBlockingPeriod value)
- {
- Debug.Assert(Enum.GetNames(typeof(PoolBlockingPeriod)).Length == 3, "PoolBlockingPeriod enum has changed, update needed");
- return value == PoolBlockingPeriod.Auto || value == PoolBlockingPeriod.AlwaysBlock || value == PoolBlockingPeriod.NeverBlock;
- }
-
- internal static string PoolBlockingPeriodToString(PoolBlockingPeriod value)
- {
- Debug.Assert(IsValidPoolBlockingPeriodValue(value));
-
- return value switch
- {
- PoolBlockingPeriod.AlwaysBlock => nameof(PoolBlockingPeriod.AlwaysBlock),
- PoolBlockingPeriod.NeverBlock => nameof(PoolBlockingPeriod.NeverBlock),
- _ => nameof(PoolBlockingPeriod.Auto),
- };
- }
-
- ///
- /// This method attempts to convert the given value to a PoolBlockingPeriod enum. The algorithm is:
- /// * if the value is from type string, it will be matched against PoolBlockingPeriod enum names only, using ordinal, case-insensitive comparer
- /// * if the value is from type PoolBlockingPeriod, it will be used as is
- /// * if the value is from integral type (SByte, Int16, Int32, Int64, Byte, UInt16, UInt32, or UInt64), it will be converted to enum
- /// * if the value is another enum or any other type, it will be blocked with an appropriate ArgumentException
- ///
- /// in any case above, if the converted value is out of valid range, the method raises ArgumentOutOfRangeException.
- ///
- /// PoolBlockingPeriod value in the valid range
- internal static PoolBlockingPeriod ConvertToPoolBlockingPeriod(string keyword, object value)
- {
- Debug.Assert(value != null, "ConvertToPoolBlockingPeriod(null)");
- if (value is string sValue)
- {
- // We could use Enum.TryParse here, but it accepts value combinations like
- // "ReadOnly, ReadWrite" which are unwelcome here
- // Also, Enum.TryParse is 100x slower than plain StringComparer.OrdinalIgnoreCase.Equals method.
-
- if (TryConvertToPoolBlockingPeriod(sValue, out PoolBlockingPeriod result))
- {
- return result;
- }
-
- // try again after remove leading & trailing whitespaces.
- sValue = sValue.Trim();
- if (TryConvertToPoolBlockingPeriod(sValue, out result))
- {
- return result;
- }
-
- // string values must be valid
- throw ADP.InvalidConnectionOptionValue(keyword);
- }
- else
- {
- // the value is not string, try other options
- PoolBlockingPeriod eValue;
-
- if (value is PoolBlockingPeriod period)
- {
- // quick path for the most common case
- eValue = period;
- }
- else if (value.GetType().IsEnum)
- {
- // explicitly block scenarios in which user tries to use wrong enum types, like:
- // builder["PoolBlockingPeriod"] = EnvironmentVariableTarget.Process;
- // workaround: explicitly cast non-PoolBlockingPeriod enums to int
- throw ADP.ConvertFailed(value.GetType(), typeof(PoolBlockingPeriod), null);
- }
- else
- {
- try
- {
- // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
- eValue = (PoolBlockingPeriod)Enum.ToObject(typeof(PoolBlockingPeriod), value);
- }
- catch (ArgumentException e)
- {
- // to be consistent with the messages we send in case of wrong type usage, replace
- // the error with our exception, and keep the original one as inner one for troubleshooting
- throw ADP.ConvertFailed(value.GetType(), typeof(PoolBlockingPeriod), e);
- }
- }
-
- // ensure value is in valid range
- if (IsValidPoolBlockingPeriodValue(eValue))
- {
- return eValue;
- }
- else
- {
- throw ADP.InvalidEnumerationValue(typeof(ApplicationIntent), (int)eValue);
- }
- }
- }
- #endregion
-
- internal static bool TryConvertToApplicationIntent(string value, out ApplicationIntent result)
- {
- Debug.Assert(Enum.GetNames(typeof(ApplicationIntent)).Length == 2, "ApplicationIntent enum has changed, update needed");
- Debug.Assert(value != null, "TryConvertToApplicationIntent(null,...)");
-
- if (StringComparer.OrdinalIgnoreCase.Equals(value, nameof(ApplicationIntent.ReadOnly)))
- {
- result = ApplicationIntent.ReadOnly;
- return true;
- }
- else if (StringComparer.OrdinalIgnoreCase.Equals(value, nameof(ApplicationIntent.ReadWrite)))
- {
- result = ApplicationIntent.ReadWrite;
- return true;
- }
- else
- {
- result = DbConnectionStringDefaults.ApplicationIntent;
- return false;
- }
- }
-
- internal static bool IsValidApplicationIntentValue(ApplicationIntent value)
- {
- Debug.Assert(Enum.GetNames(typeof(ApplicationIntent)).Length == 2, "ApplicationIntent enum has changed, update needed");
- return value == ApplicationIntent.ReadOnly || value == ApplicationIntent.ReadWrite;
- }
-
- internal static string ApplicationIntentToString(ApplicationIntent value)
- {
- Debug.Assert(IsValidApplicationIntentValue(value));
- if (value == ApplicationIntent.ReadOnly)
- {
- return nameof(ApplicationIntent.ReadOnly);
- }
- else
- {
- return nameof(ApplicationIntent.ReadWrite);
- }
- }
-
- ///
- /// This method attempts to convert the given value tp ApplicationIntent enum. The algorithm is:
- /// * if the value is from type string, it will be matched against ApplicationIntent enum names only, using ordinal, case-insensitive comparer
- /// * if the value is from type ApplicationIntent, it will be used as is
- /// * if the value is from integral type (SByte, Int16, Int32, Int64, Byte, UInt16, UInt32, or UInt64), it will be converted to enum
- /// * if the value is another enum or any other type, it will be blocked with an appropriate ArgumentException
- ///
- /// in any case above, if the converted value is out of valid range, the method raises ArgumentOutOfRangeException.
- ///
- /// application intent value in the valid range
- internal static ApplicationIntent ConvertToApplicationIntent(string keyword, object value)
- {
- Debug.Assert(value != null, "ConvertToApplicationIntent(null)");
- if (value is string sValue)
- {
- // We could use Enum.TryParse here, but it accepts value combinations like
- // "ReadOnly, ReadWrite" which are unwelcome here
- // Also, Enum.TryParse is 100x slower than plain StringComparer.OrdinalIgnoreCase.Equals method.
-
- if (TryConvertToApplicationIntent(sValue, out ApplicationIntent result))
- {
- return result;
- }
-
- // try again after remove leading & trailing whitespaces.
- sValue = sValue.Trim();
- if (TryConvertToApplicationIntent(sValue, out result))
- {
- return result;
- }
-
- // string values must be valid
- throw ADP.InvalidConnectionOptionValue(keyword);
- }
- else
- {
- // the value is not string, try other options
- ApplicationIntent eValue;
-
- if (value is ApplicationIntent intent)
- {
- // quick path for the most common case
- eValue = intent;
- }
- else if (value.GetType().IsEnum)
- {
- // explicitly block scenarios in which user tries to use wrong enum types, like:
- // builder["ApplicationIntent"] = EnvironmentVariableTarget.Process;
- // workaround: explicitly cast non-ApplicationIntent enums to int
- throw ADP.ConvertFailed(value.GetType(), typeof(ApplicationIntent), null);
- }
- else
- {
- try
- {
- // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
- eValue = (ApplicationIntent)Enum.ToObject(typeof(ApplicationIntent), value);
- }
- catch (ArgumentException e)
- {
- // to be consistent with the messages we send in case of wrong type usage, replace
- // the error with our exception, and keep the original one as inner one for troubleshooting
- throw ADP.ConvertFailed(value.GetType(), typeof(ApplicationIntent), e);
- }
- }
-
- // ensure value is in valid range
- if (IsValidApplicationIntentValue(eValue))
- {
- return eValue;
- }
- else
- {
- throw ADP.InvalidEnumerationValue(typeof(ApplicationIntent), (int)eValue);
- }
- }
- }
-
- const string SqlPasswordString = "Sql Password";
- const string ActiveDirectoryPasswordString = "Active Directory Password";
- const string ActiveDirectoryIntegratedString = "Active Directory Integrated";
- const string ActiveDirectoryInteractiveString = "Active Directory Interactive";
- const string ActiveDirectoryServicePrincipalString = "Active Directory Service Principal";
- const string ActiveDirectoryDeviceCodeFlowString = "Active Directory Device Code Flow";
- internal const string ActiveDirectoryManagedIdentityString = "Active Directory Managed Identity";
- internal const string ActiveDirectoryMSIString = "Active Directory MSI";
- internal const string ActiveDirectoryDefaultString = "Active Directory Default";
- internal const string ActiveDirectoryWorkloadIdentityString = "Active Directory Workload Identity";
-
-#if DEBUG
- private static readonly string[] s_supportedAuthenticationModes =
- {
- "NotSpecified",
- "SqlPassword",
- "ActiveDirectoryPassword",
- "ActiveDirectoryIntegrated",
- "ActiveDirectoryInteractive",
- "ActiveDirectoryServicePrincipal",
- "ActiveDirectoryDeviceCodeFlow",
- "ActiveDirectoryManagedIdentity",
- "ActiveDirectoryMSI",
- "ActiveDirectoryDefault",
- "ActiveDirectoryWorkloadIdentity",
- };
-
- private static bool IsValidAuthenticationMethodEnum()
- {
- string[] names = Enum.GetNames(typeof(SqlAuthenticationMethod));
- int l = s_supportedAuthenticationModes.Length;
- bool listValid;
- if (listValid = names.Length == l)
- {
- for (int i = 0; i < l; i++)
- {
- if (string.Compare(s_supportedAuthenticationModes[i], names[i], StringComparison.Ordinal) != 0)
- {
- listValid = false;
- }
- }
- }
- return listValid;
- }
-#endif
-
- internal static bool TryConvertToAuthenticationType(string value, out SqlAuthenticationMethod result)
- {
-#if DEBUG
- Debug.Assert(IsValidAuthenticationMethodEnum(), "SqlAuthenticationMethod enum has changed, update needed");
-#endif
- bool isSuccess = false;
-
- if (StringComparer.InvariantCultureIgnoreCase.Equals(value, SqlPasswordString)
- || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.SqlPassword, CultureInfo.InvariantCulture)))
- {
- result = SqlAuthenticationMethod.SqlPassword;
- isSuccess = true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryPasswordString)
- || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryPassword, CultureInfo.InvariantCulture)))
- {
- result = SqlAuthenticationMethod.ActiveDirectoryPassword;
- isSuccess = true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryIntegratedString)
- || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryIntegrated, CultureInfo.InvariantCulture)))
- {
- result = SqlAuthenticationMethod.ActiveDirectoryIntegrated;
- isSuccess = true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryInteractiveString)
- || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryInteractive, CultureInfo.InvariantCulture)))
- {
- result = SqlAuthenticationMethod.ActiveDirectoryInteractive;
- isSuccess = true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryServicePrincipalString)
- || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryServicePrincipal, CultureInfo.InvariantCulture)))
- {
- result = SqlAuthenticationMethod.ActiveDirectoryServicePrincipal;
- isSuccess = true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryDeviceCodeFlowString)
- || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow, CultureInfo.InvariantCulture)))
- {
- result = SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow;
- isSuccess = true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryManagedIdentityString)
- || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryManagedIdentity, CultureInfo.InvariantCulture)))
- {
- result = SqlAuthenticationMethod.ActiveDirectoryManagedIdentity;
- isSuccess = true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryMSIString)
- || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryMSI, CultureInfo.InvariantCulture)))
- {
- result = SqlAuthenticationMethod.ActiveDirectoryMSI;
- isSuccess = true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryDefaultString)
- || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryDefault, CultureInfo.InvariantCulture)))
- {
- result = SqlAuthenticationMethod.ActiveDirectoryDefault;
- isSuccess = true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryWorkloadIdentityString)
- || StringComparer.InvariantCultureIgnoreCase.Equals(value, Convert.ToString(SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity, CultureInfo.InvariantCulture)))
- {
- result = SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity;
- isSuccess = true;
- }
- else
- {
- result = DbConnectionStringDefaults.Authentication;
- }
- return isSuccess;
- }
-
- ///
- /// Convert a string value to the corresponding SqlConnectionColumnEncryptionSetting.
- ///
- ///
- ///
- ///
- internal static bool TryConvertToColumnEncryptionSetting(string value, out SqlConnectionColumnEncryptionSetting result)
- {
- bool isSuccess = false;
-
- if (StringComparer.InvariantCultureIgnoreCase.Equals(value, nameof(SqlConnectionColumnEncryptionSetting.Enabled)))
- {
- result = SqlConnectionColumnEncryptionSetting.Enabled;
- isSuccess = true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, nameof(SqlConnectionColumnEncryptionSetting.Disabled)))
- {
- result = SqlConnectionColumnEncryptionSetting.Disabled;
- isSuccess = true;
- }
- else
- {
- result = DbConnectionStringDefaults.ColumnEncryptionSetting;
- }
-
- return isSuccess;
- }
-
- ///
- /// Is it a valid connection level column encryption setting ?
- ///
- ///
- ///
- internal static bool IsValidColumnEncryptionSetting(SqlConnectionColumnEncryptionSetting value)
- {
- Debug.Assert(Enum.GetNames(typeof(SqlConnectionColumnEncryptionSetting)).Length == 2, "SqlConnectionColumnEncryptionSetting enum has changed, update needed");
- return value == SqlConnectionColumnEncryptionSetting.Enabled || value == SqlConnectionColumnEncryptionSetting.Disabled;
- }
-
- ///
- /// Convert connection level column encryption setting value to string.
- ///
- ///
- ///
- internal static string ColumnEncryptionSettingToString(SqlConnectionColumnEncryptionSetting value)
- {
- Debug.Assert(IsValidColumnEncryptionSetting(value), "value is not a valid connection level column encryption setting.");
-
- return value switch
- {
- SqlConnectionColumnEncryptionSetting.Enabled => nameof(SqlConnectionColumnEncryptionSetting.Enabled),
- SqlConnectionColumnEncryptionSetting.Disabled => nameof(SqlConnectionColumnEncryptionSetting.Disabled),
- _ => null,
- };
- }
-
- internal static bool IsValidAuthenticationTypeValue(SqlAuthenticationMethod value)
- {
- Debug.Assert(Enum.GetNames(typeof(SqlAuthenticationMethod)).Length == 11, "SqlAuthenticationMethod enum has changed, update needed");
- return value == SqlAuthenticationMethod.SqlPassword
- || value == SqlAuthenticationMethod.ActiveDirectoryPassword
- || value == SqlAuthenticationMethod.ActiveDirectoryIntegrated
- || value == SqlAuthenticationMethod.ActiveDirectoryInteractive
- || value == SqlAuthenticationMethod.ActiveDirectoryServicePrincipal
- || value == SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow
- || value == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity
- || value == SqlAuthenticationMethod.ActiveDirectoryMSI
- || value == SqlAuthenticationMethod.ActiveDirectoryDefault
- || value == SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity
- || value == SqlAuthenticationMethod.NotSpecified;
- }
-
- internal static string AuthenticationTypeToString(SqlAuthenticationMethod value)
- {
- Debug.Assert(IsValidAuthenticationTypeValue(value));
-
- return value switch
- {
- SqlAuthenticationMethod.SqlPassword => SqlPasswordString,
- SqlAuthenticationMethod.ActiveDirectoryPassword => ActiveDirectoryPasswordString,
- SqlAuthenticationMethod.ActiveDirectoryIntegrated => ActiveDirectoryIntegratedString,
- SqlAuthenticationMethod.ActiveDirectoryInteractive => ActiveDirectoryInteractiveString,
- SqlAuthenticationMethod.ActiveDirectoryServicePrincipal => ActiveDirectoryServicePrincipalString,
- SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow => ActiveDirectoryDeviceCodeFlowString,
- SqlAuthenticationMethod.ActiveDirectoryManagedIdentity => ActiveDirectoryManagedIdentityString,
- SqlAuthenticationMethod.ActiveDirectoryMSI => ActiveDirectoryMSIString,
- SqlAuthenticationMethod.ActiveDirectoryDefault => ActiveDirectoryDefaultString,
- SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity => ActiveDirectoryWorkloadIdentityString,
- _ => null
- };
- }
-
- internal static SqlAuthenticationMethod ConvertToAuthenticationType(string keyword, object value)
- {
- if (value == null)
- {
- return DbConnectionStringDefaults.Authentication;
- }
-
- if (value is string sValue)
- {
- if (TryConvertToAuthenticationType(sValue, out SqlAuthenticationMethod result))
- {
- return result;
- }
-
- // try again after remove leading & trailing whitespaces.
- sValue = sValue.Trim();
- if (TryConvertToAuthenticationType(sValue, out result))
- {
- return result;
- }
-
- // string values must be valid
- throw ADP.InvalidConnectionOptionValue(keyword);
- }
- else
- {
- // the value is not string, try other options
- SqlAuthenticationMethod eValue;
-
- if (value is SqlAuthenticationMethod method)
- {
- // quick path for the most common case
- eValue = method;
- }
- else if (value.GetType().IsEnum)
- {
- // explicitly block scenarios in which user tries to use wrong enum types, like:
- // builder["ApplicationIntent"] = EnvironmentVariableTarget.Process;
- // workaround: explicitly cast non-ApplicationIntent enums to int
- throw ADP.ConvertFailed(value.GetType(), typeof(SqlAuthenticationMethod), null);
- }
- else
- {
- try
- {
- // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
- eValue = (SqlAuthenticationMethod)Enum.ToObject(typeof(SqlAuthenticationMethod), value);
- }
- catch (ArgumentException e)
- {
- // to be consistent with the messages we send in case of wrong type usage, replace
- // the error with our exception, and keep the original one as inner one for troubleshooting
- throw ADP.ConvertFailed(value.GetType(), typeof(SqlAuthenticationMethod), e);
- }
- }
-
- // ensure value is in valid range
- if (IsValidAuthenticationTypeValue(eValue))
- {
- return eValue;
- }
- else
- {
- throw ADP.InvalidEnumerationValue(typeof(SqlAuthenticationMethod), (int)eValue);
- }
- }
- }
-
- ///
- /// Convert the provided value to a SqlConnectionColumnEncryptionSetting.
- ///
- ///
- ///
- ///
- internal static SqlConnectionColumnEncryptionSetting ConvertToColumnEncryptionSetting(string keyword, object value)
- {
- if (value == null)
- {
- return DbConnectionStringDefaults.ColumnEncryptionSetting;
- }
-
- if (value is string sValue)
- {
- if (TryConvertToColumnEncryptionSetting(sValue, out SqlConnectionColumnEncryptionSetting result))
- {
- return result;
- }
-
- // try again after remove leading & trailing whitespaces.
- sValue = sValue.Trim();
- if (TryConvertToColumnEncryptionSetting(sValue, out result))
- {
- return result;
- }
-
- // string values must be valid
- throw ADP.InvalidConnectionOptionValue(keyword);
- }
- else
- {
- // the value is not string, try other options
- SqlConnectionColumnEncryptionSetting eValue;
-
- if (value is SqlConnectionColumnEncryptionSetting setting)
- {
- // quick path for the most common case
- eValue = setting;
- }
- else if (value.GetType().IsEnum)
- {
- // explicitly block scenarios in which user tries to use wrong enum types, like:
- // builder["SqlConnectionColumnEncryptionSetting"] = EnvironmentVariableTarget.Process;
- // workaround: explicitly cast non-SqlConnectionColumnEncryptionSetting enums to int
- throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionColumnEncryptionSetting), null);
- }
- else
- {
- try
- {
- // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
- eValue = (SqlConnectionColumnEncryptionSetting)Enum.ToObject(typeof(SqlConnectionColumnEncryptionSetting), value);
- }
- catch (ArgumentException e)
- {
- // to be consistent with the messages we send in case of wrong type usage, replace
- // the error with our exception, and keep the original one as inner one for troubleshooting
- throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionColumnEncryptionSetting), e);
- }
- }
-
- // ensure value is in valid range
- if (IsValidColumnEncryptionSetting(eValue))
- {
- return eValue;
- }
- else
- {
- throw ADP.InvalidEnumerationValue(typeof(SqlConnectionColumnEncryptionSetting), (int)eValue);
- }
- }
- }
-
- #region <>
- ///
- /// Convert a string value to the corresponding SqlConnectionAttestationProtocol
- ///
- ///
- ///
- ///
- internal static bool TryConvertToAttestationProtocol(string value, out SqlConnectionAttestationProtocol result)
- {
- if (StringComparer.InvariantCultureIgnoreCase.Equals(value, nameof(SqlConnectionAttestationProtocol.HGS)))
- {
- result = SqlConnectionAttestationProtocol.HGS;
- return true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, nameof(SqlConnectionAttestationProtocol.AAS)))
- {
- result = SqlConnectionAttestationProtocol.AAS;
- return true;
- }
- else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, nameof(SqlConnectionAttestationProtocol.None)))
- {
- result = SqlConnectionAttestationProtocol.None;
- return true;
- }
- else
- {
- result = DbConnectionStringDefaults.AttestationProtocol;
- return false;
- }
- }
-
- internal static bool IsValidAttestationProtocol(SqlConnectionAttestationProtocol value)
- {
- Debug.Assert(Enum.GetNames(typeof(SqlConnectionAttestationProtocol)).Length == 4, "SqlConnectionAttestationProtocol enum has changed, update needed");
- return value == SqlConnectionAttestationProtocol.NotSpecified
- || value == SqlConnectionAttestationProtocol.HGS
- || value == SqlConnectionAttestationProtocol.AAS
- || value == SqlConnectionAttestationProtocol.None;
- }
-
- internal static string AttestationProtocolToString(SqlConnectionAttestationProtocol value)
- {
- Debug.Assert(IsValidAttestationProtocol(value), "value is not a valid attestation protocol");
-
- return value switch
- {
- SqlConnectionAttestationProtocol.AAS => nameof(SqlConnectionAttestationProtocol.AAS),
- SqlConnectionAttestationProtocol.HGS => nameof(SqlConnectionAttestationProtocol.HGS),
- SqlConnectionAttestationProtocol.None => nameof(SqlConnectionAttestationProtocol.None),
- _ => null
- };
- }
-
- internal static SqlConnectionAttestationProtocol ConvertToAttestationProtocol(string keyword, object value)
- {
- if (value == null)
- {
- return DbConnectionStringDefaults.AttestationProtocol;
- }
-
- if (value is string sValue)
- {
- // try again after remove leading & trailing whitespaces.
- sValue = sValue.Trim();
- if (TryConvertToAttestationProtocol(sValue, out SqlConnectionAttestationProtocol result))
- {
- return result;
- }
-
- // string values must be valid
- throw ADP.InvalidConnectionOptionValue(keyword);
- }
- else
- {
- // the value is not string, try other options
- SqlConnectionAttestationProtocol eValue;
-
- if (value is SqlConnectionAttestationProtocol protocol)
- {
- eValue = protocol;
- }
- else if (value.GetType().IsEnum)
- {
- // explicitly block scenarios in which user tries to use wrong enum types, like:
- // builder["SqlConnectionAttestationProtocol"] = EnvironmentVariableTarget.Process;
- // workaround: explicitly cast non-SqlConnectionAttestationProtocol enums to int
- throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionAttestationProtocol), null);
- }
- else
- {
- try
- {
- // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
- eValue = (SqlConnectionAttestationProtocol)Enum.ToObject(typeof(SqlConnectionAttestationProtocol), value);
- }
- catch (ArgumentException e)
- {
- // to be consistent with the messages we send in case of wrong type usage, replace
- // the error with our exception, and keep the original one as inner one for troubleshooting
- throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionAttestationProtocol), e);
- }
- }
-
- if (IsValidAttestationProtocol(eValue))
- {
- return eValue;
- }
- else
- {
- throw ADP.InvalidEnumerationValue(typeof(SqlConnectionAttestationProtocol), (int)eValue);
- }
- }
- }
-
- internal static SqlConnectionEncryptOption ConvertToSqlConnectionEncryptOption(string keyword, object value)
- {
- if (value is null)
- {
- return DbConnectionStringDefaults.Encrypt;
- }
- else if(value is SqlConnectionEncryptOption eValue)
- {
- return eValue;
- }
- else if (value is string sValue)
- {
- return SqlConnectionEncryptOption.Parse(sValue);
- }
- else if(value is bool bValue)
- {
- return SqlConnectionEncryptOption.Parse(bValue);
- }
-
- throw ADP.InvalidConnectionOptionValue(keyword);
- }
-
- #endregion
-
- #region <>
- ///
- /// IP Address Preference.
- ///
- private readonly static Dictionary s_preferenceNames = new(StringComparer.InvariantCultureIgnoreCase);
-
- static DbConnectionStringBuilderUtil()
- {
- foreach (SqlConnectionIPAddressPreference item in Enum.GetValues(typeof(SqlConnectionIPAddressPreference)))
- {
- s_preferenceNames.Add(item.ToString(), item);
- }
- }
-
- ///
- /// Convert a string value to the corresponding IPAddressPreference.
- ///
- /// The string representation of the enumeration name to convert.
- /// When this method returns, `result` contains an object of type `SqlConnectionIPAddressPreference` whose value is represented by `value` if the operation succeeds.
- /// If the parse operation fails, `result` contains the default value of the `SqlConnectionIPAddressPreference` type.
- /// `true` if the value parameter was converted successfully; otherwise, `false`.
- internal static bool TryConvertToIPAddressPreference(string value, out SqlConnectionIPAddressPreference result)
- {
- if (!s_preferenceNames.TryGetValue(value, out result))
- {
- result = DbConnectionStringDefaults.IPAddressPreference;
- return false;
- }
- return true;
- }
-
- ///
- /// Verifies if the `value` is defined in the expected Enum.
- ///
- internal static bool IsValidIPAddressPreference(SqlConnectionIPAddressPreference value)
- => value == SqlConnectionIPAddressPreference.IPv4First
- || value == SqlConnectionIPAddressPreference.IPv6First
- || value == SqlConnectionIPAddressPreference.UsePlatformDefault;
-
- internal static string IPAddressPreferenceToString(SqlConnectionIPAddressPreference value)
- => Enum.GetName(typeof(SqlConnectionIPAddressPreference), value);
-
- internal static SqlConnectionIPAddressPreference ConvertToIPAddressPreference(string keyword, object value)
- {
- if (value is null)
- {
- return DbConnectionStringDefaults.IPAddressPreference; // IPv4First
- }
-
- if (value is string sValue)
- {
- // try again after remove leading & trailing whitespaces.
- sValue = sValue.Trim();
- if (TryConvertToIPAddressPreference(sValue, out SqlConnectionIPAddressPreference result))
- {
- return result;
- }
-
- // string values must be valid
- throw ADP.InvalidConnectionOptionValue(keyword);
- }
- else
- {
- // the value is not string, try other options
- SqlConnectionIPAddressPreference eValue;
-
- if (value is SqlConnectionIPAddressPreference preference)
- {
- eValue = preference;
- }
- else if (value.GetType().IsEnum)
- {
- // explicitly block scenarios in which user tries to use wrong enum types, like:
- // builder["SqlConnectionIPAddressPreference"] = EnvironmentVariableTarget.Process;
- // workaround: explicitly cast non-SqlConnectionIPAddressPreference enums to int
- throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionIPAddressPreference), null);
- }
- else
- {
- try
- {
- // Enum.ToObject allows only integral and enum values (enums are blocked above), raising ArgumentException for the rest
- eValue = (SqlConnectionIPAddressPreference)Enum.ToObject(typeof(SqlConnectionIPAddressPreference), value);
- }
- catch (ArgumentException e)
- {
- // to be consistent with the messages we send in case of wrong type usage, replace
- // the error with our exception, and keep the original one as inner one for troubleshooting
- throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionIPAddressPreference), e);
- }
- }
-
- if (IsValidIPAddressPreference(eValue))
- {
- return eValue;
- }
- else
- {
- throw ADP.InvalidEnumerationValue(typeof(SqlConnectionIPAddressPreference), (int)eValue);
- }
- }
- }
- #endregion
- }
-
- internal static class DbConnectionStringDefaults
- {
- internal const ApplicationIntent ApplicationIntent = Microsoft.Data.SqlClient.ApplicationIntent.ReadWrite;
- internal const string ApplicationName =
-#if NETFRAMEWORK
- "Framework Microsoft SqlClient Data Provider";
-#else
- "Core Microsoft SqlClient Data Provider";
-#endif
- internal const string AttachDBFilename = "";
- internal const int CommandTimeout = 30;
- internal const int ConnectTimeout = 15;
- internal const bool ContextConnection = false;
-
-#if NETFRAMEWORK
- internal const bool ConnectionReset = true;
- internal static readonly bool TransparentNetworkIPResolution = !LocalAppContextSwitches.DisableTNIRByDefault;
- internal const string NetworkLibrary = "";
-#endif
- internal const string CurrentLanguage = "";
- internal const string DataSource = "";
- internal static readonly SqlConnectionEncryptOption Encrypt = SqlConnectionEncryptOption.Mandatory;
- internal const string HostNameInCertificate = "";
- internal const string ServerCertificate = "";
- internal const bool Enlist = true;
- internal const string FailoverPartner = "";
- internal const string InitialCatalog = "";
- internal const bool IntegratedSecurity = false;
- internal const int LoadBalanceTimeout = 0; // default of 0 means don't use
- internal const bool MultipleActiveResultSets = false;
- internal const bool MultiSubnetFailover = false;
- internal const int MaxPoolSize = 100;
- internal const int MinPoolSize = 0;
- internal const int PacketSize = 8000;
- internal const string Password = "";
- internal const bool PersistSecurityInfo = false;
- internal const bool Pooling = true;
- internal const bool TrustServerCertificate = false;
- internal const string TypeSystemVersion = "Latest";
- internal const string UserID = "";
- internal const bool UserInstance = false;
- internal const bool Replication = false;
- internal const string WorkstationID = "";
- internal const string TransactionBinding = "Implicit Unbind";
- internal const int ConnectRetryCount = 1;
- internal const int ConnectRetryInterval = 10;
- internal static readonly SqlAuthenticationMethod Authentication = SqlAuthenticationMethod.NotSpecified;
- internal const SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled;
- internal const string EnclaveAttestationUrl = "";
- internal const SqlConnectionAttestationProtocol AttestationProtocol = SqlConnectionAttestationProtocol.NotSpecified;
- internal const SqlConnectionIPAddressPreference IPAddressPreference = SqlConnectionIPAddressPreference.IPv4First;
- internal const PoolBlockingPeriod PoolBlockingPeriod = SqlClient.PoolBlockingPeriod.Auto;
- internal const string ServerSPN = "";
- internal const string FailoverPartnerSPN = "";
- }
-
- internal static class DbConnectionStringKeywords
- {
-#if NETFRAMEWORK
- // Odbc
- internal const string Driver = "Driver";
- internal const string Dsn = "Dsn";
- internal const string FileDsn = "FileDsn";
- internal const string SaveFile = "SaveFile";
-
- // OleDb
- internal const string FileName = "File Name";
- internal const string OleDbServices = "OLE DB Services";
- internal const string Provider = "Provider";
-
- // OracleClient
- internal const string Unicode = "Unicode";
- internal const string OmitOracleConnectionName = "Omit Oracle Connection Name";
-#endif
- // SqlClient
- internal const string ApplicationIntent = "Application Intent";
- internal const string ApplicationName = "Application Name";
- internal const string AttachDBFilename = "AttachDbFilename";
- internal const string ConnectTimeout = "Connect Timeout";
- internal const string CommandTimeout = "Command Timeout";
- internal const string ConnectionReset = "Connection Reset";
- internal const string ContextConnection = "Context Connection";
- internal const string CurrentLanguage = "Current Language";
- internal const string Encrypt = "Encrypt";
- internal const string HostNameInCertificate = "Host Name In Certificate";
- internal const string ServerCertificate = "Server Certificate";
- internal const string FailoverPartner = "Failover Partner";
- internal const string InitialCatalog = "Initial Catalog";
- internal const string MultipleActiveResultSets = "Multiple Active Result Sets";
- internal const string MultiSubnetFailover = "Multi Subnet Failover";
- internal const string NetworkLibrary = "Network Library";
- internal const string PacketSize = "Packet Size";
- internal const string Replication = "Replication";
- internal const string TransactionBinding = "Transaction Binding";
- internal const string TrustServerCertificate = "Trust Server Certificate";
- internal const string TypeSystemVersion = "Type System Version";
- internal const string UserInstance = "User Instance";
- internal const string WorkstationID = "Workstation ID";
- internal const string ConnectRetryCount = "Connect Retry Count";
- internal const string ConnectRetryInterval = "Connect Retry Interval";
- internal const string Authentication = "Authentication";
- internal const string ColumnEncryptionSetting = "Column Encryption Setting";
- internal const string EnclaveAttestationUrl = "Enclave Attestation Url";
- internal const string AttestationProtocol = "Attestation Protocol";
- internal const string IPAddressPreference = "IP Address Preference";
- internal const string ServerSPN = "Server SPN";
- internal const string FailoverPartnerSPN = "Failover Partner SPN";
- internal const string TransparentNetworkIPResolution = "Transparent Network IP Resolution";
-
- // common keywords (OleDb, OracleClient, SqlClient)
- internal const string DataSource = "Data Source";
- internal const string IntegratedSecurity = "Integrated Security";
- internal const string Password = "Password";
- internal const string PersistSecurityInfo = "Persist Security Info";
- internal const string UserID = "User ID";
-
- // managed pooling (OracleClient, SqlClient)
- internal const string Enlist = "Enlist";
- internal const string LoadBalanceTimeout = "Load Balance Timeout";
- internal const string MaxPoolSize = "Max Pool Size";
- internal const string Pooling = "Pooling";
- internal const string MinPoolSize = "Min Pool Size";
- internal const string PoolBlockingPeriod = "Pool Blocking Period";
- }
-
- internal static class DbConnectionStringSynonyms
- {
- //internal const string TransparentNetworkIPResolution = TRANSPARENTNETWORKIPRESOLUTION;
- internal const string TRANSPARENTNETWORKIPRESOLUTION = "transparentnetworkipresolution";
-
- //internal const string ApplicationName = APP;
- internal const string APP = "app";
-
- // internal const string IPAddressPreference = IPADDRESSPREFERENCE;
- internal const string IPADDRESSPREFERENCE = "ipaddresspreference";
-
- //internal const string ApplicationIntent = APPLICATIONINTENT;
- internal const string APPLICATIONINTENT = "applicationintent";
-
- //internal const string AttachDBFilename = EXTENDEDPROPERTIES+","+INITIALFILENAME;
- internal const string EXTENDEDPROPERTIES = "extended properties";
- internal const string INITIALFILENAME = "initial file name";
-
- // internal const string HostNameInCertificate = HOSTNAMEINCERTIFICATE;
- internal const string HOSTNAMEINCERTIFICATE = "hostnameincertificate";
-
- // internal const string ServerCertificate = SERVERCERTIFICATE;
- internal const string SERVERCERTIFICATE = "servercertificate";
-
- //internal const string ConnectTimeout = CONNECTIONTIMEOUT+","+TIMEOUT;
- internal const string CONNECTIONTIMEOUT = "connection timeout";
- internal const string TIMEOUT = "timeout";
-
- //internal const string ConnectRetryCount = CONNECTRETRYCOUNT;
- internal const string CONNECTRETRYCOUNT = "connectretrycount";
-
- //internal const string ConnectRetryInterval = CONNECTRETRYINTERVAL;
- internal const string CONNECTRETRYINTERVAL = "connectretryinterval";
-
- //internal const string CurrentLanguage = LANGUAGE;
- internal const string LANGUAGE = "language";
-
- //internal const string OraDataSource = SERVER;
- //internal const string SqlDataSource = ADDR+","+ADDRESS+","+SERVER+","+NETWORKADDRESS;
- internal const string ADDR = "addr";
- internal const string ADDRESS = "address";
- internal const string SERVER = "server";
- internal const string NETWORKADDRESS = "network address";
-
- //internal const string InitialCatalog = DATABASE;
- internal const string DATABASE = "database";
-
- //internal const string IntegratedSecurity = TRUSTEDCONNECTION;
- internal const string TRUSTEDCONNECTION = "trusted_connection"; // underscore introduced in everett
-
- //internal const string LoadBalanceTimeout = ConnectionLifetime;
- internal const string ConnectionLifetime = "connection lifetime";
-
- //internal const string MultipleActiveResultSets = MULTIPLEACTIVERESULTSETS;
- internal const string MULTIPLEACTIVERESULTSETS = "multipleactiveresultsets";
-
- //internal const string MultiSubnetFailover = MULTISUBNETFAILOVER;
- internal const string MULTISUBNETFAILOVER = "multisubnetfailover";
-
- //internal const string NetworkLibrary = NET+","+NETWORK;
- internal const string NET = "net";
- internal const string NETWORK = "network";
-
- //internal const string PoolBlockingPeriod = POOLBLOCKINGPERIOD;
- internal const string POOLBLOCKINGPERIOD = "poolblockingperiod";
-
- //internal const string Password = Pwd;
- internal const string Pwd = "pwd";
-
- //internal const string PersistSecurityInfo = PERSISTSECURITYINFO;
- internal const string PERSISTSECURITYINFO = "persistsecurityinfo";
-
- //internal const string TrustServerCertificate = TRUSTSERVERCERTIFICATE;
- internal const string TRUSTSERVERCERTIFICATE = "trustservercertificate";
-
- //internal const string UserID = UID+","+User;
- internal const string UID = "uid";
- internal const string User = "user";
-
- //internal const string WorkstationID = WSID;
- internal const string WSID = "wsid";
-
- //internal const string server SPNs
- internal const string ServerSPN = "ServerSPN";
- internal const string FailoverPartnerSPN = "FailoverPartnerSPN";
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs
index a4982981f2..9b9767dae5 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ActiveDirectoryAuthenticationProvider.cs
@@ -10,6 +10,7 @@
using System.Threading.Tasks;
using Azure.Core;
using Azure.Identity;
+using Microsoft.Data.Common.ConnectionString;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Identity.Client;
using Microsoft.Identity.Client.Extensibility;
@@ -549,7 +550,7 @@ private IPublicClientApplication CreateClientAppInstance(PublicClientAppKey publ
{
publicClientApplication = PublicClientApplicationBuilder.Create(publicClientAppKey._applicationClientId)
.WithAuthority(publicClientAppKey._authority)
- .WithClientName(Common.DbConnectionStringDefaults.ApplicationName)
+ .WithClientName(DbConnectionStringDefaults.ApplicationName)
.WithClientVersion(Common.ADP.GetAssemblyVersion().ToString())
.WithRedirectUri(publicClientAppKey._redirectUri)
.WithParentActivityOrWindow(_iWin32WindowFunc)
@@ -560,7 +561,7 @@ private IPublicClientApplication CreateClientAppInstance(PublicClientAppKey publ
{
publicClientApplication = PublicClientApplicationBuilder.Create(publicClientAppKey._applicationClientId)
.WithAuthority(publicClientAppKey._authority)
- .WithClientName(Common.DbConnectionStringDefaults.ApplicationName)
+ .WithClientName(DbConnectionStringDefaults.ApplicationName)
.WithClientVersion(Common.ADP.GetAssemblyVersion().ToString())
.WithRedirectUri(publicClientAppKey._redirectUri)
.Build();
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 58b34fd287..245ea3e45f 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs
@@ -13,6 +13,7 @@
using System.Security;
using System.Security.Permissions;
using Microsoft.Data.Common;
+using Microsoft.Data.Common.ConnectionString;
using Microsoft.Data.SqlClient.LocalDb;
namespace Microsoft.Data.SqlClient
@@ -23,6 +24,7 @@ internal sealed class SqlConnectionString : DbConnectionOptions
// used by pooling classes so it is much easier to verify correctness
// when not worried about the class being modified during execution
+ // @TODO: Remove this in favor of using DbConnectionStringDefaults??
internal static class DEFAULT
{
internal const ApplicationIntent ApplicationIntent = DbConnectionStringDefaults.ApplicationIntent;
@@ -71,6 +73,7 @@ internal static class DEFAULT
#endif // NETFRAMEWORK
}
+ // @TODO: Remove in favor of DbConnectionStringKeywords
// SqlConnection ConnectionString Options
internal static class KEY
{
@@ -126,6 +129,7 @@ internal static class KEY
#endif // NETFRAMEWORK
}
+ // @TODO: Remove in favor DbConnectionStringSynonyms
// Constant for the number of duplicate options in the connection string
private static class SYNONYM
{
@@ -575,22 +579,22 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity && _hasPasswordKeyword)
{
- throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryManagedIdentityString);
+ throw SQL.NonInteractiveWithPassword(DbConnectionStringUtilities.ActiveDirectoryManagedIdentityString);
}
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryMSI && _hasPasswordKeyword)
{
- throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryMSIString);
+ throw SQL.NonInteractiveWithPassword(DbConnectionStringUtilities.ActiveDirectoryMSIString);
}
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryDefault && _hasPasswordKeyword)
{
- throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString);
+ throw SQL.NonInteractiveWithPassword(DbConnectionStringUtilities.ActiveDirectoryDefaultString);
}
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryWorkloadIdentity && _hasPasswordKeyword)
{
- throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryWorkloadIdentityString);
+ throw SQL.NonInteractiveWithPassword(DbConnectionStringUtilities.ActiveDirectoryWorkloadIdentityString);
}
}
@@ -941,7 +945,7 @@ internal ApplicationIntent ConvertValueToApplicationIntent()
// wrap Format and Overflow exceptions with Argument one, to be consistent with rest of the keyword types (like int and bool)
try
{
- return DbConnectionStringBuilderUtil.ConvertToApplicationIntent(KEY.ApplicationIntent, value);
+ return DbConnectionStringUtilities.ConvertToApplicationIntent(KEY.ApplicationIntent, value);
}
catch (FormatException e)
{
@@ -973,7 +977,7 @@ internal SqlAuthenticationMethod ConvertValueToAuthenticationType()
try
{
- return DbConnectionStringBuilderUtil.ConvertToAuthenticationType(KEY.Authentication, value);
+ return DbConnectionStringUtilities.ConvertToAuthenticationType(KEY.Authentication, value);
}
catch (FormatException e)
{
@@ -998,7 +1002,7 @@ internal SqlConnectionColumnEncryptionSetting ConvertValueToColumnEncryptionSett
try
{
- return DbConnectionStringBuilderUtil.ConvertToColumnEncryptionSetting(KEY.ColumnEncryptionSetting, value);
+ return DbConnectionStringUtilities.ConvertToColumnEncryptionSetting(KEY.ColumnEncryptionSetting, value);
}
catch (FormatException e)
{
@@ -1023,7 +1027,7 @@ internal SqlConnectionAttestationProtocol ConvertValueToAttestationProtocol()
try
{
- return DbConnectionStringBuilderUtil.ConvertToAttestationProtocol(KEY.AttestationProtocol, value);
+ return AttestationProtocolUtilities.ConvertToAttestationProtocol(KEY.AttestationProtocol, value);
}
catch (FormatException e)
{
@@ -1048,7 +1052,7 @@ internal SqlConnectionIPAddressPreference ConvertValueToIPAddressPreference()
try
{
- return DbConnectionStringBuilderUtil.ConvertToIPAddressPreference(KEY.IPAddressPreference, value);
+ return IpAddressPreferenceUtilities.ConvertToIPAddressPreference(KEY.IPAddressPreference, value);
}
catch (FormatException e)
{
@@ -1069,7 +1073,7 @@ internal PoolBlockingPeriod ConvertValueToPoolBlockingPeriod()
try
{
- return DbConnectionStringBuilderUtil.ConvertToPoolBlockingPeriod(KEY.PoolBlockingPeriod, value);
+ return PoolBlockingUtilities.ConvertToPoolBlockingPeriod(KEY.PoolBlockingPeriod, value);
}
catch (Exception e) when (e is FormatException || e is OverflowException)
{
@@ -1086,7 +1090,7 @@ internal SqlConnectionEncryptOption ConvertValueToSqlConnectionEncrypt()
try
{
- return DbConnectionStringBuilderUtil.ConvertToSqlConnectionEncryptOption(KEY.Encrypt, value);
+ return AttestationProtocolUtilities.ConvertToSqlConnectionEncryptOption(KEY.Encrypt, value);
}
catch (FormatException e)
{
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 4ed5c59198..c86aeccb3c 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionStringBuilder.cs
@@ -15,6 +15,7 @@
using System.Globalization;
using System.Reflection;
using Microsoft.Data.Common;
+using Microsoft.Data.Common.ConnectionString;
namespace Microsoft.Data.SqlClient
{
@@ -274,34 +275,35 @@ private static Dictionary CreateKeywordsDictionary()
Debug.Assert((KeywordsCount + SqlConnectionString.SynonymCount) == pairs.Count, "initial expected size is incorrect");
return pairs;
}
+
+ // @TODO These methods are completely unnecessary.
- private static bool ConvertToBoolean(object value) => DbConnectionStringBuilderUtil.ConvertToBoolean(value);
+ private static bool ConvertToBoolean(object value) => DbConnectionStringUtilities.ConvertToBoolean(value);
- private static int ConvertToInt32(object value) => DbConnectionStringBuilderUtil.ConvertToInt32(value);
+ private static int ConvertToInt32(object value) => DbConnectionStringUtilities.ConvertToInt32(value);
- private static bool ConvertToIntegratedSecurity(object value) => DbConnectionStringBuilderUtil.ConvertToIntegratedSecurity(value);
+ private static bool ConvertToIntegratedSecurity(object value) => DbConnectionStringUtilities.ConvertToIntegratedSecurity(value);
- private static SqlAuthenticationMethod ConvertToAuthenticationType(string keyword, object value) => DbConnectionStringBuilderUtil.ConvertToAuthenticationType(keyword, value);
+ private static SqlAuthenticationMethod ConvertToAuthenticationType(string keyword, object value) => DbConnectionStringUtilities.ConvertToAuthenticationType(keyword, value);
- private static string ConvertToString(object value) => DbConnectionStringBuilderUtil.ConvertToString(value);
+ private static string ConvertToString(object value) => DbConnectionStringUtilities.ConvertToString(value);
- private static ApplicationIntent ConvertToApplicationIntent(string keyword, object value) => DbConnectionStringBuilderUtil.ConvertToApplicationIntent(keyword, value);
+ private static ApplicationIntent ConvertToApplicationIntent(string keyword, object value) => DbConnectionStringUtilities.ConvertToApplicationIntent(keyword, value);
private static SqlConnectionColumnEncryptionSetting ConvertToColumnEncryptionSetting(string keyword, object value)
- => DbConnectionStringBuilderUtil.ConvertToColumnEncryptionSetting(keyword, value);
+ => DbConnectionStringUtilities.ConvertToColumnEncryptionSetting(keyword, value);
private static SqlConnectionAttestationProtocol ConvertToAttestationProtocol(string keyword, object value)
- => DbConnectionStringBuilderUtil.ConvertToAttestationProtocol(keyword, value);
+ => AttestationProtocolUtilities.ConvertToAttestationProtocol(keyword, value);
private static SqlConnectionEncryptOption ConvertToSqlConnectionEncryptOption(string keyword, object value)
- => DbConnectionStringBuilderUtil.ConvertToSqlConnectionEncryptOption(keyword, value);
-
+ => AttestationProtocolUtilities.ConvertToSqlConnectionEncryptOption(keyword, value);
private static SqlConnectionIPAddressPreference ConvertToIPAddressPreference(string keyword, object value)
- => DbConnectionStringBuilderUtil.ConvertToIPAddressPreference(keyword, value);
+ => IpAddressPreferenceUtilities.ConvertToIPAddressPreference(keyword, value);
private static PoolBlockingPeriod ConvertToPoolBlockingPeriod(string keyword, object value)
- => DbConnectionStringBuilderUtil.ConvertToPoolBlockingPeriod(keyword, value);
+ => PoolBlockingUtilities.ConvertToPoolBlockingPeriod(keyword, value);
private object GetAt(Keywords index)
{
@@ -559,6 +561,8 @@ 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);
@@ -571,20 +575,20 @@ private void SetValue(string keyword, string value)
private void SetApplicationIntentValue(ApplicationIntent value)
{
- Debug.Assert(DbConnectionStringBuilderUtil.IsValidApplicationIntentValue(value), "invalid value for ApplicationIntent");
- base[DbConnectionStringKeywords.ApplicationIntent] = DbConnectionStringBuilderUtil.ApplicationIntentToString(value);
+ Debug.Assert(DbConnectionStringUtilities.IsValidApplicationIntentValue(value), "invalid value for ApplicationIntent");
+ base[DbConnectionStringKeywords.ApplicationIntent] = DbConnectionStringUtilities.ApplicationIntentToString(value);
}
private void SetColumnEncryptionSettingValue(SqlConnectionColumnEncryptionSetting value)
{
- Debug.Assert(DbConnectionStringBuilderUtil.IsValidColumnEncryptionSetting(value), "Invalid value for SqlConnectionColumnEncryptionSetting");
- base[DbConnectionStringKeywords.ColumnEncryptionSetting] = DbConnectionStringBuilderUtil.ColumnEncryptionSettingToString(value);
+ Debug.Assert(DbConnectionStringUtilities.IsValidColumnEncryptionSetting(value), "Invalid value for SqlConnectionColumnEncryptionSetting");
+ base[DbConnectionStringKeywords.ColumnEncryptionSetting] = DbConnectionStringUtilities.ColumnEncryptionSettingToString(value);
}
private void SetAttestationProtocolValue(SqlConnectionAttestationProtocol value)
{
- Debug.Assert(DbConnectionStringBuilderUtil.IsValidAttestationProtocol(value), "Invalid value for SqlConnectionAttestationProtocol");
- base[DbConnectionStringKeywords.AttestationProtocol] = DbConnectionStringBuilderUtil.AttestationProtocolToString(value);
+ Debug.Assert(AttestationProtocolUtilities.IsValidAttestationProtocol(value), "Invalid value for SqlConnectionAttestationProtocol");
+ base[DbConnectionStringKeywords.AttestationProtocol] = AttestationProtocolUtilities.AttestationProtocolToString(value);
}
private void SetSqlConnectionEncryptionValue(SqlConnectionEncryptOption value)
@@ -594,20 +598,20 @@ private void SetSqlConnectionEncryptionValue(SqlConnectionEncryptOption value)
private void SetIPAddressPreferenceValue(SqlConnectionIPAddressPreference value)
{
- Debug.Assert(DbConnectionStringBuilderUtil.IsValidIPAddressPreference(value), "Invalid value for SqlConnectionIPAddressPreference");
- base[DbConnectionStringKeywords.IPAddressPreference] = DbConnectionStringBuilderUtil.IPAddressPreferenceToString(value);
+ Debug.Assert(IpAddressPreferenceUtilities.IsValidIPAddressPreference(value), "Invalid value for SqlConnectionIPAddressPreference");
+ base[DbConnectionStringKeywords.IPAddressPreference] = IpAddressPreferenceUtilities.IPAddressPreferenceToString(value);
}
private void SetAuthenticationValue(SqlAuthenticationMethod value)
{
- Debug.Assert(DbConnectionStringBuilderUtil.IsValidAuthenticationTypeValue(value), "Invalid value for AuthenticationType");
- base[DbConnectionStringKeywords.Authentication] = DbConnectionStringBuilderUtil.AuthenticationTypeToString(value);
+ Debug.Assert(DbConnectionStringUtilities.IsValidAuthenticationTypeValue(value), "Invalid value for AuthenticationType");
+ base[DbConnectionStringKeywords.Authentication] = DbConnectionStringUtilities.AuthenticationTypeToString(value);
}
private void SetPoolBlockingPeriodValue(PoolBlockingPeriod value)
{
- Debug.Assert(DbConnectionStringBuilderUtil.IsValidPoolBlockingPeriodValue(value), "Invalid value for PoolBlockingPeriod");
- base[DbConnectionStringKeywords.PoolBlockingPeriod] = DbConnectionStringBuilderUtil.PoolBlockingPeriodToString(value);
+ Debug.Assert(PoolBlockingUtilities.IsValidPoolBlockingPeriodValue(value), "Invalid value for PoolBlockingPeriod");
+ base[DbConnectionStringKeywords.PoolBlockingPeriod] = PoolBlockingUtilities.PoolBlockingPeriodToString(value);
}
private Exception UnsupportedKeyword(string keyword)
@@ -1091,7 +1095,7 @@ public ApplicationIntent ApplicationIntent
get => _applicationIntent;
set
{
- if (!DbConnectionStringBuilderUtil.IsValidApplicationIntentValue(value))
+ if (!DbConnectionStringUtilities.IsValidApplicationIntentValue(value))
{
throw ADP.InvalidEnumerationValue(typeof(ApplicationIntent), (int)value);
}
@@ -1274,7 +1278,7 @@ public SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting
get => _columnEncryptionSetting;
set
{
- if (!DbConnectionStringBuilderUtil.IsValidColumnEncryptionSetting(value))
+ if (!DbConnectionStringUtilities.IsValidColumnEncryptionSetting(value))
{
throw ADP.InvalidEnumerationValue(typeof(SqlConnectionColumnEncryptionSetting), (int)value);
}
@@ -1309,7 +1313,7 @@ public SqlConnectionAttestationProtocol AttestationProtocol
get => _attestationProtocol;
set
{
- if (!DbConnectionStringBuilderUtil.IsValidAttestationProtocol(value))
+ if (!AttestationProtocolUtilities.IsValidAttestationProtocol(value))
{
throw ADP.InvalidEnumerationValue(typeof(SqlConnectionAttestationProtocol), (int)value);
}
@@ -1329,7 +1333,7 @@ public SqlConnectionIPAddressPreference IPAddressPreference
get => _ipAddressPreference;
set
{
- if (!DbConnectionStringBuilderUtil.IsValidIPAddressPreference(value))
+ if (!IpAddressPreferenceUtilities.IsValidIPAddressPreference(value))
{
throw ADP.InvalidEnumerationValue(typeof(SqlConnectionIPAddressPreference), (int)value);
}
@@ -1443,7 +1447,7 @@ public SqlAuthenticationMethod Authentication
get => _authentication;
set
{
- if (!DbConnectionStringBuilderUtil.IsValidAuthenticationTypeValue(value))
+ if (!DbConnectionStringUtilities.IsValidAuthenticationTypeValue(value))
{
throw ADP.InvalidEnumerationValue(typeof(SqlAuthenticationMethod), (int)value);
}
@@ -1640,7 +1644,7 @@ public PoolBlockingPeriod PoolBlockingPeriod
get => _poolBlockingPeriod;
set
{
- if (!DbConnectionStringBuilderUtil.IsValidPoolBlockingPeriodValue(value))
+ if (!PoolBlockingUtilities.IsValidPoolBlockingPeriodValue(value))
{
throw ADP.InvalidEnumerationValue(typeof(PoolBlockingPeriod), (int)value);
}
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs
index c398110849..835f1ae640 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs
@@ -492,7 +492,7 @@ static internal Exception UserInstanceFailoverNotCompatible()
}
static internal Exception CredentialsNotProvided(SqlAuthenticationMethod auth)
{
- return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CredentialsNotProvided, DbConnectionStringBuilderUtil.AuthenticationTypeToString(auth)));
+ return ADP.InvalidOperation(StringsHelper.GetString(Strings.SQL_CredentialsNotProvided, DbConnectionStringUtilities.AuthenticationTypeToString(auth)));
}
static internal Exception InvalidCertAuth()
{
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs
index 18f60d0724..280469a5e0 100644
--- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsEnums.cs
@@ -4,6 +4,7 @@
using System;
using System.Data;
+using Microsoft.Data.Common.ConnectionString;
namespace Microsoft.Data.SqlClient
{
@@ -14,7 +15,7 @@ internal static class TdsEnums
// internal tdsparser constants
- public const string SQL_PROVIDER_NAME = Common.DbConnectionStringDefaults.ApplicationName;
+ public const string SQL_PROVIDER_NAME = DbConnectionStringDefaults.ApplicationName;
public static readonly decimal SQL_SMALL_MONEY_MIN = new(-214748.3648);
public static readonly decimal SQL_SMALL_MONEY_MAX = new(214748.3647);