Skip to content

Commit 6ac1e49

Browse files
Merging common code bases DBConnectionOptions (#1279)
1 parent a77f2ae commit 6ac1e49

File tree

12 files changed

+314
-1266
lines changed

12 files changed

+314
-1266
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
<Compile Include="..\..\src\Microsoft\Data\Common\NameValuePair.cs">
5656
<Link>Microsoft\Data\Common\NameValuePair.cs</Link>
5757
</Compile>
58+
<Compile Include="..\..\src\Microsoft\Data\Common\DbConnectionOptions.Common.cs">
59+
<Link>Microsoft\Data\Common\DbConnectionOptions.Common.cs</Link>
60+
</Compile>
5861
<Compile Include="..\..\src\Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs">
5962
<Link>Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs</Link>
6063
</Compile>
@@ -450,9 +453,6 @@
450453
</Compile>
451454
<Compile Include="Microsoft\Data\Common\AdapterUtil.SqlClient.cs" />
452455
<Compile Include="Microsoft\Data\Common\DbConnectionOptions.cs" />
453-
<Compile Include="$(CommonPath)\Microsoft\Data\Common\DbConnectionOptions.Common.cs">
454-
<Link>Microsoft\Data\Common\DbConnectionOptions.Common.cs</Link>
455-
</Compile>
456456
<Compile Include="Microsoft\Data\Common\DbConnectionStringCommon.cs" />
457457
<Compile Include="$(CommonPath)\Microsoft\Data\ProviderBase\DbConnectionInternal.cs">
458458
<Link>Common\Microsoft\Data\ProviderBase\DbConnectionInternal.cs</Link>

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Common/DbConnectionOptions.cs

Lines changed: 11 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -3,113 +3,32 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6-
using System.Collections.Generic;
7-
using System.Globalization;
86
using System.IO;
97
using System.Text;
108

119
namespace Microsoft.Data.Common
1210
{
1311
internal partial class DbConnectionOptions
1412
{
15-
// instances of this class are intended to be immutable, i.e readonly
16-
// used by pooling classes so it is much easier to verify correctness
17-
// when not worried about the class being modified during execution
18-
19-
public DbConnectionOptions(string connectionString, Dictionary<string, string> synonyms)
20-
{
21-
_parsetable = new Dictionary<string, string>();
22-
_usersConnectionString = ((null != connectionString) ? connectionString : "");
23-
24-
// first pass on parsing, initial syntax check
25-
if (0 < _usersConnectionString.Length)
26-
{
27-
_keyChain = ParseInternal(_parsetable, _usersConnectionString, true, synonyms, false);
28-
HasPasswordKeyword = (_parsetable.ContainsKey(KEY.Password) || _parsetable.ContainsKey(SYNONYM.Pwd));
29-
HasUserIdKeyword = (_parsetable.ContainsKey(KEY.User_ID) || _parsetable.ContainsKey(SYNONYM.UID));
30-
}
31-
}
32-
33-
protected DbConnectionOptions(DbConnectionOptions connectionOptions)
34-
{ // Clone used by SqlConnectionString
35-
_usersConnectionString = connectionOptions._usersConnectionString;
36-
_parsetable = connectionOptions._parsetable;
37-
_keyChain = connectionOptions._keyChain;
38-
HasPasswordKeyword = connectionOptions.HasPasswordKeyword;
39-
HasUserIdKeyword = connectionOptions.HasUserIdKeyword;
40-
}
41-
42-
public bool IsEmpty => _keyChain == null;
43-
44-
internal bool TryGetParsetableValue(string key, out string value) => _parsetable.TryGetValue(key, out value);
45-
46-
// same as Boolean, but with SSPI thrown in as valid yes
47-
public bool ConvertValueToIntegratedSecurity()
13+
internal string ExpandAttachDbFileName(string replacementValue)
4814
{
49-
string value;
50-
return _parsetable.TryGetValue(KEY.Integrated_Security, out value) && value != null ?
51-
ConvertValueToIntegratedSecurityInternal(value) :
52-
false;
53-
}
15+
int copyPosition = 0;
5416

55-
internal bool ConvertValueToIntegratedSecurityInternal(string stringValue)
56-
{
57-
if (CompareInsensitiveInvariant(stringValue, "sspi") || CompareInsensitiveInvariant(stringValue, "true") || CompareInsensitiveInvariant(stringValue, "yes"))
58-
return true;
59-
else if (CompareInsensitiveInvariant(stringValue, "false") || CompareInsensitiveInvariant(stringValue, "no"))
60-
return false;
61-
else
17+
StringBuilder builder = new(_usersConnectionString.Length);
18+
for (NameValuePair current = _keyChain; null != current; current = current.Next)
6219
{
63-
string tmp = stringValue.Trim(); // Remove leading & trailing whitespace.
64-
if (CompareInsensitiveInvariant(tmp, "sspi") || CompareInsensitiveInvariant(tmp, "true") || CompareInsensitiveInvariant(tmp, "yes"))
65-
return true;
66-
else if (CompareInsensitiveInvariant(tmp, "false") || CompareInsensitiveInvariant(tmp, "no"))
67-
return false;
20+
if (string.Equals(current.Name, DbConnectionStringKeywords.AttachDBFilename, StringComparison.InvariantCultureIgnoreCase))
21+
{
22+
builder.Append($"{current.Name}={replacementValue};");
23+
}
6824
else
6925
{
70-
throw ADP.InvalidConnectionOptionValue(KEY.Integrated_Security);
26+
builder.Append(_usersConnectionString, copyPosition, current.Length);
7127
}
28+
copyPosition += current.Length;
7229
}
73-
}
74-
75-
public int ConvertValueToInt32(string keyName, int defaultValue)
76-
{
77-
string value;
78-
return _parsetable.TryGetValue(keyName, out value) && value != null ?
79-
ConvertToInt32Internal(keyName, value) :
80-
defaultValue;
81-
}
82-
83-
internal static int ConvertToInt32Internal(string keyname, string stringValue)
84-
{
85-
try
86-
{
87-
return int.Parse(stringValue, System.Globalization.NumberStyles.Integer, CultureInfo.InvariantCulture);
88-
}
89-
catch (FormatException e)
90-
{
91-
throw ADP.InvalidConnectionOptionValue(keyname, e);
92-
}
93-
catch (OverflowException e)
94-
{
95-
throw ADP.InvalidConnectionOptionValue(keyname, e);
96-
}
97-
}
9830

99-
public string ConvertValueToString(string keyName, string defaultValue)
100-
{
101-
string value;
102-
return _parsetable.TryGetValue(keyName, out value) && value != null ? value : defaultValue;
103-
}
104-
105-
public bool ContainsKey(string keyword)
106-
{
107-
return _parsetable.ContainsKey(keyword);
108-
}
109-
110-
protected internal virtual string Expand()
111-
{
112-
return _usersConnectionString;
31+
return builder.ToString();
11332
}
11433

11534
// SxS notes:
@@ -151,25 +70,5 @@ internal static string ExpandDataDirectory(string keyword, string value)
15170
return fullPath;
15271
}
15372

154-
internal string ExpandAttachDbFileName(string replacementValue)
155-
{
156-
int copyPosition = 0;
157-
158-
StringBuilder builder = new StringBuilder(_usersConnectionString.Length);
159-
for (NameValuePair current = _keyChain; null != current; current = current.Next)
160-
{
161-
if (current.Name == KEY.AttachDBFileName)
162-
{
163-
builder.Append($"{KEY.AttachDBFileName}={replacementValue};");
164-
}
165-
else
166-
{
167-
builder.Append(_usersConnectionString, copyPosition, current.Length);
168-
}
169-
copyPosition += current.Length;
170-
}
171-
172-
return builder.ToString();
173-
}
17473
}
17574
}

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1820,7 +1820,7 @@ private bool TryOpen(TaskCompletionSource<DbConnectionInternal> retry, SqlConnec
18201820
(connectionOptions.Authentication == SqlAuthenticationMethod.SqlPassword ||
18211821
connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryPassword ||
18221822
connectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryServicePrincipal) &&
1823-
(!connectionOptions.HasUserIdKeyword || !connectionOptions.HasPasswordKeyword) &&
1823+
(!connectionOptions._hasUserIdKeyword || !connectionOptions._hasPasswordKeyword) &&
18241824
_credential == null)
18251825
{
18261826
throw SQL.CredentialsNotProvided(connectionOptions.Authentication);

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionString.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -456,32 +456,32 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G
456456
throw SQL.AuthenticationAndIntegratedSecurity();
457457
}
458458

459-
if (Authentication == SqlClient.SqlAuthenticationMethod.ActiveDirectoryIntegrated && HasPasswordKeyword)
459+
if (Authentication == SqlClient.SqlAuthenticationMethod.ActiveDirectoryIntegrated && _hasPasswordKeyword)
460460
{
461461
throw SQL.IntegratedWithPassword();
462462
}
463463

464-
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive && HasPasswordKeyword)
464+
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive && _hasPasswordKeyword)
465465
{
466466
throw SQL.InteractiveWithPassword();
467467
}
468468

469-
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow && (HasUserIdKeyword || HasPasswordKeyword))
469+
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow && (_hasUserIdKeyword || _hasPasswordKeyword))
470470
{
471471
throw SQL.DeviceFlowWithUsernamePassword();
472472
}
473473

474-
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity && HasPasswordKeyword)
474+
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity && _hasPasswordKeyword)
475475
{
476476
throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryManagedIdentityString);
477477
}
478478

479-
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryMSI && HasPasswordKeyword)
479+
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryMSI && _hasPasswordKeyword)
480480
{
481481
throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryMSIString);
482482
}
483483

484-
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryDefault && HasPasswordKeyword)
484+
if (Authentication == SqlAuthenticationMethod.ActiveDirectoryDefault && _hasPasswordKeyword)
485485
{
486486
throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString);
487487
}

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2117,7 +2117,7 @@ internal void OnLoginAck(SqlLoginAck rec)
21172117
/// <param name="fedAuthInfo">Federated Authentication Info.</param>
21182118
internal void OnFedAuthInfo(SqlFedAuthInfo fedAuthInfo)
21192119
{
2120-
Debug.Assert((ConnectionOptions.HasUserIdKeyword && ConnectionOptions.HasPasswordKeyword)
2120+
Debug.Assert((ConnectionOptions._hasUserIdKeyword && ConnectionOptions._hasPasswordKeyword)
21212121
|| _credential != null
21222122
|| ConnectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive
21232123
|| ConnectionOptions.Authentication == SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow

src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@
110110
<Compile Include="..\..\src\Microsoft\Data\Common\NameValuePair.cs">
111111
<Link>Microsoft\Data\Common\NameValuePair.cs</Link>
112112
</Compile>
113+
<Compile Include="..\..\src\Microsoft\Data\Common\DbConnectionOptions.Common.cs">
114+
<Link>Microsoft\Data\Common\DbConnectionOptions.Common.cs</Link>
115+
</Compile>
113116
<Compile Include="..\..\src\Microsoft\Data\Sql\SqlNotificationRequest.cs">
114117
<Link>Microsoft\Data\Sql\SqlNotificationRequest.cs</Link>
115118
</Compile>

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/Common/DBConnectionString.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@ internal sealed class DBConnectionString
2323

2424
private static class KEY
2525
{
26-
internal const string Password = "password";
27-
internal const string PersistSecurityInfo = "persist security info";
28-
internal const string Pwd = "pwd";
26+
internal const string Password = DbConnectionStringKeywords.Password;
27+
internal const string PersistSecurityInfo = DbConnectionStringKeywords.PersistSecurityInfo;
28+
internal const string Pwd = DbConnectionStringSynonyms.Pwd;
2929
};
3030

3131
// this class is serializable with Everett, so ugly field names can't be changed
3232
readonly private string _encryptedUsersConnectionString;
3333

3434
// hash of unique keys to values
35-
readonly private Hashtable _parsetable;
35+
readonly private Dictionary<string, string> _parsetable;
3636

3737
// a linked list of key/value and their length in _encryptedUsersConnectionString
3838
readonly private NameValuePair _keychain;
@@ -52,21 +52,21 @@ private static class KEY
5252
readonly private string _encryptedActualConnectionString;
5353
#pragma warning restore 169
5454

55-
internal DBConnectionString(string value, string restrictions, KeyRestrictionBehavior behavior, Hashtable synonyms, bool useOdbcRules)
56-
: this(new DbConnectionOptions(value, synonyms, useOdbcRules), restrictions, behavior, synonyms, false)
55+
internal DBConnectionString(string value, string restrictions, KeyRestrictionBehavior behavior, Dictionary<string, string> synonyms, bool useOdbcRules)
56+
: this(new DbConnectionOptions(value, synonyms), restrictions, behavior, synonyms, false)
5757
{
5858
// useOdbcRules is only used to parse the connection string, not to parse restrictions because values don't apply there
5959
// the hashtable doesn't need clone since it isn't shared with anything else
6060
}
6161

6262
internal DBConnectionString(DbConnectionOptions connectionOptions)
63-
: this(connectionOptions, (string)null, KeyRestrictionBehavior.AllowOnly, (Hashtable)null, true)
63+
: this(connectionOptions, (string)null, KeyRestrictionBehavior.AllowOnly, null, true)
6464
{
6565
// used by DBDataPermission to convert from DbConnectionOptions to DBConnectionString
6666
// since backward compatibility requires Everett level classes
6767
}
6868

69-
private DBConnectionString(DbConnectionOptions connectionOptions, string restrictions, KeyRestrictionBehavior behavior, Hashtable synonyms, bool mustCloneDictionary)
69+
private DBConnectionString(DbConnectionOptions connectionOptions, string restrictions, KeyRestrictionBehavior behavior, Dictionary<string, string> synonyms, bool mustCloneDictionary)
7070
{ // used by DBDataPermission
7171
Debug.Assert(null != connectionOptions, "null connectionOptions");
7272
switch (behavior)
@@ -81,9 +81,9 @@ private DBConnectionString(DbConnectionOptions connectionOptions, string restric
8181

8282
// grab all the parsed details from DbConnectionOptions
8383
_encryptedUsersConnectionString = connectionOptions.UsersConnectionString(false);
84-
_hasPassword = connectionOptions.HasPasswordKeyword;
84+
_hasPassword = connectionOptions._hasPasswordKeyword;
8585
_parsetable = connectionOptions.Parsetable;
86-
_keychain = connectionOptions.KeyChain;
86+
_keychain = connectionOptions._keyChain;
8787

8888
// we do not want to serialize out user password unless directed so by "persist security info=true"
8989
// otherwise all instances of user's password will be replaced with "*"
@@ -94,7 +94,7 @@ private DBConnectionString(DbConnectionOptions connectionOptions, string restric
9494
{
9595
// clone the hashtable to replace user's password/pwd value with "*"
9696
// we only need to clone if coming from DbConnectionOptions and password exists
97-
_parsetable = (Hashtable)_parsetable.Clone();
97+
_parsetable = new Dictionary<string, string>(_parsetable, _parsetable.Comparer);
9898
}
9999

100100
// different than Everett in that instead of removing password/pwd from
@@ -467,7 +467,7 @@ static private string[] NoDuplicateUnion(string[] a, string[] b)
467467
return restrictionValues;
468468
}
469469

470-
private static string[] ParseRestrictions(string restrictions, Hashtable synonyms)
470+
private static string[] ParseRestrictions(string restrictions, Dictionary<string, string> synonyms)
471471
{
472472
#if DEBUG
473473
SqlClientEventSource.Log.TryAdvancedTraceEvent("<comm.DBConnectionString|INFO|ADV> Restrictions='{0}'", restrictions);

0 commit comments

Comments
 (0)