1 //------------------------------------------------------------------------------
2 // <copyright file="DbConnectionStringBuilder.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 //------------------------------------------------------------------------------
10 using System.Collections;
11 using System.Collections.Generic;
12 using System.ComponentModel;
14 using System.Data.Common;
15 using System.Diagnostics;
16 using System.Globalization;
17 using System.Runtime.Serialization;
18 using System.Security.Permissions;
20 using System.Text.RegularExpressions;
21 using System.Data.SqlClient;
23 namespace System.Data.Common {
26 internal sealed class NamedConnectionStringConverter : StringConverter {
28 public NamedConnectionStringConverter() {
31 public override bool GetStandardValuesSupported(ITypeDescriptorContext context) {
35 public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) {
36 // Although theoretically this could be true, some people may want to just type in a name
40 public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) {
41 StandardValuesCollection standardValues = null;
42 if (null != context) {
43 DbConnectionStringBuilder instance = (context.Instance as DbConnectionStringBuilder);
44 if (null != instance) {
45 string myProviderName = instance.GetType().Namespace;
47 List<string> myConnectionNames = new List<string>();
48 foreach(System.Configuration.ConnectionStringSetting setting in System.Configuration.ConfigurationManager.ConnectionStrings) {
49 if (myProviderName.EndsWith(setting.ProviderName)) {
50 myConnectionNames.Add(setting.ConnectionName);
53 standardValues = new StandardValuesCollection(myConnectionNames);
56 return standardValues;
61 internal class DbConnectionStringBuilderDescriptor : PropertyDescriptor {
62 private Type _componentType;
63 private Type _propertyType;
64 private bool _isReadOnly;
65 private bool _refreshOnChange;
67 internal DbConnectionStringBuilderDescriptor(string propertyName, Type componentType, Type propertyType, bool isReadOnly, Attribute[] attributes) : base(propertyName, attributes) {
68 //Bid.Trace("<comm.DbConnectionStringBuilderDescriptor|INFO> propertyName='%ls', propertyType='%ls'\n", propertyName, propertyType.Name);
69 _componentType = componentType;
70 _propertyType = propertyType;
71 _isReadOnly = isReadOnly;
74 internal bool RefreshOnChange {
76 return _refreshOnChange;
79 _refreshOnChange = value;
83 public override Type ComponentType {
85 return _componentType;
88 public override bool IsReadOnly {
93 public override Type PropertyType {
98 public override bool CanResetValue(object component) {
99 DbConnectionStringBuilder builder = (component as DbConnectionStringBuilder);
100 return ((null != builder) && builder.ShouldSerialize(DisplayName));
102 public override object GetValue(object component) {
103 DbConnectionStringBuilder builder = (component as DbConnectionStringBuilder);
104 if (null != builder) {
106 if (builder.TryGetValue(DisplayName, out value)) {
112 public override void ResetValue(object component) {
113 DbConnectionStringBuilder builder = (component as DbConnectionStringBuilder);
114 if (null != builder) {
115 builder.Remove(DisplayName);
117 if (RefreshOnChange) {
118 builder.ClearPropertyDescriptors();
122 public override void SetValue(object component, object value) {
123 DbConnectionStringBuilder builder = (component as DbConnectionStringBuilder);
124 if (null != builder) {
125 // via the editor, empty string does a defacto Reset
126 if ((typeof(string) == PropertyType) && String.Empty.Equals(value)) {
129 builder[DisplayName] = value;
131 if (RefreshOnChange) {
132 builder.ClearPropertyDescriptors();
136 public override bool ShouldSerializeValue(object component) {
137 DbConnectionStringBuilder builder = (component as DbConnectionStringBuilder);
138 return ((null != builder) && builder.ShouldSerialize(DisplayName));
143 internal sealed class ReadOnlyCollection<T> : System.Collections.ICollection, ICollection<T> {
146 internal ReadOnlyCollection(T[] items) {
149 for(int i = 0; i < items.Length; ++i) {
150 Debug.Assert(null != items[i], "null item");
155 public void CopyTo(T[] array, int arrayIndex) {
156 Array.Copy(_items, 0, array, arrayIndex, _items.Length);
159 void System.Collections.ICollection.CopyTo(Array array, int arrayIndex) {
160 Array.Copy(_items, 0, array, arrayIndex, _items.Length);
164 IEnumerator<T> IEnumerable<T>.GetEnumerator() {
165 return new Enumerator<T>(_items);
168 public System.Collections.IEnumerator GetEnumerator() {
169 return new Enumerator<T>(_items);
172 bool System.Collections.ICollection.IsSynchronized {
173 get { return false; }
176 Object System.Collections.ICollection.SyncRoot {
177 get { return _items; }
180 bool ICollection<T>.IsReadOnly {
184 void ICollection<T>.Add(T value) {
185 throw new NotSupportedException();
188 void ICollection<T>.Clear() {
189 throw new NotSupportedException();
192 bool ICollection<T>.Contains(T value) {
193 return Array.IndexOf(_items, value) >= 0;
196 bool ICollection<T>.Remove(T value) {
197 throw new NotSupportedException();
201 get { return _items.Length; }
205 internal struct Enumerator<K> : IEnumerator<K>, System.Collections.IEnumerator { // based on List<T>.Enumerator
209 internal Enumerator(K[] items) {
214 public void Dispose() {
217 public bool MoveNext() {
218 return (++_index < _items.Length);
223 return _items[_index];
227 Object System.Collections.IEnumerator.Current {
229 return _items[_index];
233 void System.Collections.IEnumerator.Reset() {
239 internal static class DbConnectionStringBuilderUtil
242 internal static bool ConvertToBoolean(object value)
244 Debug.Assert(null != value, "ConvertToBoolean(null)");
245 string svalue = (value as string);
248 if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes"))
250 else if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "false") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "no"))
254 string tmp = svalue.Trim(); // Remove leading & trailing white space.
255 if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "true") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "yes"))
257 else if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "false") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "no"))
260 return Boolean.Parse(svalue);
264 return ((IConvertible)value).ToBoolean(CultureInfo.InvariantCulture);
266 catch (InvalidCastException e)
268 throw ADP.ConvertFailed(value.GetType(), typeof(Boolean), e);
272 internal static bool ConvertToIntegratedSecurity(object value)
274 Debug.Assert(null != value, "ConvertToIntegratedSecurity(null)");
275 string svalue = (value as string);
278 if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "sspi") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes"))
280 else if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "false") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "no"))
284 string tmp = svalue.Trim(); // Remove leading & trailing white space.
285 if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "sspi") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "true") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "yes"))
287 else if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "false") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "no"))
290 return Boolean.Parse(svalue);
294 return ((IConvertible)value).ToBoolean(CultureInfo.InvariantCulture);
296 catch (InvalidCastException e)
298 throw ADP.ConvertFailed(value.GetType(), typeof(Boolean), e);
302 internal static int ConvertToInt32(object value)
306 return ((IConvertible)value).ToInt32(CultureInfo.InvariantCulture);
308 catch (InvalidCastException e)
310 throw ADP.ConvertFailed(value.GetType(), typeof(Int32), e);
314 internal static string ConvertToString(object value)
318 return ((IConvertible)value).ToString(CultureInfo.InvariantCulture);
320 catch (InvalidCastException e)
322 throw ADP.ConvertFailed(value.GetType(), typeof(String), e);
326 #region <<PoolBlockingPeriod Utility>>
327 const string PoolBlockingPeriodAutoString = "Auto";
328 const string PoolBlockingPeriodAlwaysBlockString = "AlwaysBlock";
329 const string PoolBlockingPeriodNeverBlockString = "NeverBlock";
331 internal static bool TryConvertToPoolBlockingPeriod(string value, out PoolBlockingPeriod result)
333 Debug.Assert(Enum.GetNames(typeof(PoolBlockingPeriod)).Length == 3, "PoolBlockingPeriod enum has changed, update needed");
334 Debug.Assert(null != value, "TryConvertToPoolBlockingPeriod(null,...)");
336 if (StringComparer.OrdinalIgnoreCase.Equals(value, PoolBlockingPeriodAutoString))
338 result = PoolBlockingPeriod.Auto;
341 else if (StringComparer.OrdinalIgnoreCase.Equals(value, PoolBlockingPeriodAlwaysBlockString))
343 result = PoolBlockingPeriod.AlwaysBlock;
346 else if (StringComparer.OrdinalIgnoreCase.Equals(value, PoolBlockingPeriodNeverBlockString))
348 result = PoolBlockingPeriod.NeverBlock;
353 result = DbConnectionStringDefaults.PoolBlockingPeriod;
358 internal static bool IsValidPoolBlockingPeriodValue(PoolBlockingPeriod value)
360 Debug.Assert(Enum.GetNames(typeof(PoolBlockingPeriod)).Length == 3, "PoolBlockingPeriod enum has changed, update needed");
361 return value == PoolBlockingPeriod.Auto || value == PoolBlockingPeriod.AlwaysBlock || value == PoolBlockingPeriod.NeverBlock;
364 internal static string PoolBlockingPeriodToString(PoolBlockingPeriod value)
366 Debug.Assert(IsValidPoolBlockingPeriodValue(value));
368 if (value == PoolBlockingPeriod.AlwaysBlock)
370 return PoolBlockingPeriodAlwaysBlockString;
372 if (value == PoolBlockingPeriod.NeverBlock)
374 return PoolBlockingPeriodNeverBlockString;
378 return PoolBlockingPeriodAutoString;
383 /// This method attempts to convert the given value to a PoolBlockingPeriod enum. The algorithm is:
384 /// * if the value is from type string, it will be matched against PoolBlockingPeriod enum names only, using ordinal, case-insensitive comparer
385 /// * if the value is from type PoolBlockingPeriod, it will be used as is
386 /// * if the value is from integral type (SByte, Int16, Int32, Int64, Byte, UInt16, UInt32, or UInt64), it will be converted to enum
387 /// * if the value is another enum or any other type, it will be blocked with an appropriate ArgumentException
389 /// in any case above, if the conerted value is out of valid range, the method raises ArgumentOutOfRangeException.
391 /// <returns>PoolBlockingPeriod value in the valid range</returns>
392 internal static PoolBlockingPeriod ConvertToPoolBlockingPeriod(string keyword, object value)
394 Debug.Assert(null != value, "ConvertToPoolBlockingPeriod(null)");
395 string sValue = (value as string);
396 PoolBlockingPeriod result;
399 // We could use Enum.TryParse<PoolBlockingPeriod> here, but it accepts value combinations like
400 // "ReadOnly, ReadWrite" which are unwelcome here
401 // Also, Enum.TryParse is 100x slower than plain StringComparer.OrdinalIgnoreCase.Equals method.
403 if (TryConvertToPoolBlockingPeriod(sValue, out result))
408 // try again after remove leading & trailing whitespaces.
409 sValue = sValue.Trim();
410 if (TryConvertToPoolBlockingPeriod(sValue, out result))
415 // string values must be valid
416 throw ADP.InvalidConnectionOptionValue(keyword);
420 // the value is not string, try other options
421 PoolBlockingPeriod eValue;
423 if (value is PoolBlockingPeriod)
425 // quick path for the most common case
426 eValue = (PoolBlockingPeriod)value;
428 else if (value.GetType().IsEnum)
430 // explicitly block scenarios in which user tries to use wrong enum types, like:
431 // builder["PoolBlockingPeriod"] = EnvironmentVariableTarget.Process;
432 // workaround: explicitly cast non-PoolBlockingPeriod enums to int
433 throw ADP.ConvertFailed(value.GetType(), typeof(PoolBlockingPeriod), null);
439 // Enum.ToObject allows only integral and enum values (enums are blocked above), rasing ArgumentException for the rest
440 eValue = (PoolBlockingPeriod)Enum.ToObject(typeof(PoolBlockingPeriod), value);
442 catch (ArgumentException e)
444 // to be consistent with the messages we send in case of wrong type usage, replace
445 // the error with our exception, and keep the original one as inner one for troubleshooting
446 throw ADP.ConvertFailed(value.GetType(), typeof(PoolBlockingPeriod), e);
450 // ensure value is in valid range
451 if (IsValidPoolBlockingPeriodValue(eValue))
457 throw ADP.InvalidEnumerationValue(typeof(ApplicationIntent), (int)eValue);
463 const string ApplicationIntentReadWriteString = "ReadWrite";
464 const string ApplicationIntentReadOnlyString = "ReadOnly";
466 internal static bool TryConvertToApplicationIntent(string value, out ApplicationIntent result)
468 Debug.Assert(Enum.GetNames(typeof(ApplicationIntent)).Length == 2, "ApplicationIntent enum has changed, update needed");
469 Debug.Assert(null != value, "TryConvertToApplicationIntent(null,...)");
471 if (StringComparer.OrdinalIgnoreCase.Equals(value, ApplicationIntentReadOnlyString))
473 result = ApplicationIntent.ReadOnly;
476 else if (StringComparer.OrdinalIgnoreCase.Equals(value, ApplicationIntentReadWriteString))
478 result = ApplicationIntent.ReadWrite;
483 result = DbConnectionStringDefaults.ApplicationIntent;
488 internal static bool IsValidApplicationIntentValue(ApplicationIntent value)
490 Debug.Assert(Enum.GetNames(typeof(ApplicationIntent)).Length == 2, "ApplicationIntent enum has changed, update needed");
491 return value == ApplicationIntent.ReadOnly || value == ApplicationIntent.ReadWrite;
494 internal static string ApplicationIntentToString(ApplicationIntent value)
496 Debug.Assert(IsValidApplicationIntentValue(value));
497 if (value == ApplicationIntent.ReadOnly)
499 return ApplicationIntentReadOnlyString;
503 return ApplicationIntentReadWriteString;
508 /// This method attempts to convert the given value tp ApplicationIntent enum. The algorithm is:
509 /// * if the value is from type string, it will be matched against ApplicationIntent enum names only, using ordinal, case-insensitive comparer
510 /// * if the value is from type ApplicationIntent, it will be used as is
511 /// * if the value is from integral type (SByte, Int16, Int32, Int64, Byte, UInt16, UInt32, or UInt64), it will be converted to enum
512 /// * if the value is another enum or any other type, it will be blocked with an appropriate ArgumentException
514 /// in any case above, if the conerted value is out of valid range, the method raises ArgumentOutOfRangeException.
516 /// <returns>applicaiton intent value in the valid range</returns>
517 internal static ApplicationIntent ConvertToApplicationIntent(string keyword, object value)
519 Debug.Assert(null != value, "ConvertToApplicationIntent(null)");
520 string sValue = (value as string);
521 ApplicationIntent result;
524 // We could use Enum.TryParse<ApplicationIntent> here, but it accepts value combinations like
525 // "ReadOnly, ReadWrite" which are unwelcome here
526 // Also, Enum.TryParse is 100x slower than plain StringComparer.OrdinalIgnoreCase.Equals method.
528 if (TryConvertToApplicationIntent(sValue, out result))
533 // try again after remove leading & trailing whitespaces.
534 sValue = sValue.Trim();
535 if (TryConvertToApplicationIntent(sValue, out result))
540 // string values must be valid
541 throw ADP.InvalidConnectionOptionValue(keyword);
545 // the value is not string, try other options
546 ApplicationIntent eValue;
548 if (value is ApplicationIntent)
550 // quick path for the most common case
551 eValue = (ApplicationIntent)value;
553 else if (value.GetType().IsEnum)
555 // explicitly block scenarios in which user tries to use wrong enum types, like:
556 // builder["ApplicationIntent"] = EnvironmentVariableTarget.Process;
557 // workaround: explicitly cast non-ApplicationIntent enums to int
558 throw ADP.ConvertFailed(value.GetType(), typeof(ApplicationIntent), null);
564 // Enum.ToObject allows only integral and enum values (enums are blocked above), rasing ArgumentException for the rest
565 eValue = (ApplicationIntent)Enum.ToObject(typeof(ApplicationIntent), value);
567 catch (ArgumentException e)
569 // to be consistent with the messages we send in case of wrong type usage, replace
570 // the error with our exception, and keep the original one as inner one for troubleshooting
571 throw ADP.ConvertFailed(value.GetType(), typeof(ApplicationIntent), e);
575 // ensure value is in valid range
576 if (IsValidApplicationIntentValue(eValue))
582 throw ADP.InvalidEnumerationValue(typeof(ApplicationIntent), (int)eValue);
587 const string SqlPasswordString = "Sql Password";
588 const string ActiveDirectoryPasswordString = "Active Directory Password";
589 const string ActiveDirectoryIntegratedString = "Active Directory Integrated";
591 internal static bool TryConvertToAuthenticationType(string value, out SqlAuthenticationMethod result)
593 Debug.Assert(Enum.GetNames(typeof(SqlAuthenticationMethod)).Length == 4, "SqlAuthenticationMethod enum has changed, update needed");
595 bool isSuccess = false;
597 if (StringComparer.InvariantCultureIgnoreCase.Equals(value, SqlPasswordString))
599 result = SqlAuthenticationMethod.SqlPassword;
602 else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryPasswordString))
604 result = SqlAuthenticationMethod.ActiveDirectoryPassword;
607 else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryIntegratedString))
609 result = SqlAuthenticationMethod.ActiveDirectoryIntegrated;
614 result = DbConnectionStringDefaults.Authentication;
620 /// Column Encryption Setting.
622 const string ColumnEncryptionSettingEnabledString = "Enabled";
623 const string ColumnEncryptionSettingDisabledString = "Disabled";
626 /// Convert a string value to the corresponding SqlConnectionColumnEncryptionSetting.
628 /// <param name="value"></param>
629 /// <param name="result"></param>
630 /// <returns></returns>
631 internal static bool TryConvertToColumnEncryptionSetting(string value, out SqlConnectionColumnEncryptionSetting result) {
632 bool isSuccess = false;
634 if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ColumnEncryptionSettingEnabledString)) {
635 result = SqlConnectionColumnEncryptionSetting.Enabled;
638 else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ColumnEncryptionSettingDisabledString)) {
639 result = SqlConnectionColumnEncryptionSetting.Disabled;
643 result = DbConnectionStringDefaults.ColumnEncryptionSetting;
650 /// Is it a valid connection level column encryption setting ?
652 /// <param name="value"></param>
653 /// <returns></returns>
654 internal static bool IsValidColumnEncryptionSetting(SqlConnectionColumnEncryptionSetting value) {
655 Debug.Assert(Enum.GetNames(typeof(SqlConnectionColumnEncryptionSetting)).Length == 2, "SqlConnectionColumnEncryptionSetting enum has changed, update needed");
656 return value == SqlConnectionColumnEncryptionSetting.Enabled || value == SqlConnectionColumnEncryptionSetting.Disabled;
660 /// Convert connection level column encryption setting value to string.
662 /// <param name="value"></param>
663 /// <returns></returns>
664 internal static string ColumnEncryptionSettingToString(SqlConnectionColumnEncryptionSetting value) {
665 Debug.Assert(IsValidColumnEncryptionSetting(value), "value is not a valid connection level column encryption setting.");
668 case SqlConnectionColumnEncryptionSetting.Enabled:
669 return ColumnEncryptionSettingEnabledString;
670 case SqlConnectionColumnEncryptionSetting.Disabled:
671 return ColumnEncryptionSettingDisabledString;
678 internal static bool IsValidAuthenticationTypeValue(SqlAuthenticationMethod value) {
679 Debug.Assert(Enum.GetNames(typeof(SqlAuthenticationMethod)).Length == 4, "SqlAuthenticationMethod enum has changed, update needed");
680 return value == SqlAuthenticationMethod.SqlPassword
681 || value == SqlAuthenticationMethod.ActiveDirectoryPassword
682 || value == SqlAuthenticationMethod.ActiveDirectoryIntegrated
683 || value == SqlAuthenticationMethod.NotSpecified;
686 internal static string AuthenticationTypeToString(SqlAuthenticationMethod value)
688 Debug.Assert(IsValidAuthenticationTypeValue(value));
692 case SqlAuthenticationMethod.SqlPassword:
693 return SqlPasswordString;
694 case SqlAuthenticationMethod.ActiveDirectoryPassword:
695 return ActiveDirectoryPasswordString;
696 case SqlAuthenticationMethod.ActiveDirectoryIntegrated:
697 return ActiveDirectoryIntegratedString;
703 internal static SqlAuthenticationMethod ConvertToAuthenticationType(string keyword, object value)
707 return DbConnectionStringDefaults.Authentication;
710 string sValue = (value as string);
711 SqlAuthenticationMethod result;
714 if (TryConvertToAuthenticationType(sValue, out result))
719 // try again after remove leading & trailing whitespaces.
720 sValue = sValue.Trim();
721 if (TryConvertToAuthenticationType(sValue, out result))
726 // string values must be valid
727 throw ADP.InvalidConnectionOptionValue(keyword);
731 // the value is not string, try other options
732 SqlAuthenticationMethod eValue;
734 if (value is SqlAuthenticationMethod)
736 // quick path for the most common case
737 eValue = (SqlAuthenticationMethod)value;
739 else if (value.GetType().IsEnum)
741 // explicitly block scenarios in which user tries to use wrong enum types, like:
742 // builder["ApplicationIntent"] = EnvironmentVariableTarget.Process;
743 // workaround: explicitly cast non-ApplicationIntent enums to int
744 throw ADP.ConvertFailed(value.GetType(), typeof(SqlAuthenticationMethod), null);
750 // Enum.ToObject allows only integral and enum values (enums are blocked above), rasing ArgumentException for the rest
751 eValue = (SqlAuthenticationMethod)Enum.ToObject(typeof(SqlAuthenticationMethod), value);
753 catch (ArgumentException e)
755 // to be consistent with the messages we send in case of wrong type usage, replace
756 // the error with our exception, and keep the original one as inner one for troubleshooting
757 throw ADP.ConvertFailed(value.GetType(), typeof(SqlAuthenticationMethod), e);
761 // ensure value is in valid range
762 if (IsValidAuthenticationTypeValue(eValue))
768 throw ADP.InvalidEnumerationValue(typeof(SqlAuthenticationMethod), (int)eValue);
774 /// Convert the provided value to a SqlConnectionColumnEncryptionSetting.
776 /// <param name="keyword"></param>
777 /// <param name="value"></param>
778 /// <returns></returns>
779 internal static SqlConnectionColumnEncryptionSetting ConvertToColumnEncryptionSetting(string keyword, object value) {
781 return DbConnectionStringDefaults.ColumnEncryptionSetting;
784 string sValue = (value as string);
785 SqlConnectionColumnEncryptionSetting result;
786 if (null != sValue) {
787 if (TryConvertToColumnEncryptionSetting(sValue, out result)) {
791 // try again after remove leading & trailing whitespaces.
792 sValue = sValue.Trim();
793 if (TryConvertToColumnEncryptionSetting(sValue, out result)) {
797 // string values must be valid
798 throw ADP.InvalidConnectionOptionValue(keyword);
801 // the value is not string, try other options
802 SqlConnectionColumnEncryptionSetting eValue;
804 if (value is SqlConnectionColumnEncryptionSetting) {
805 // quick path for the most common case
806 eValue = (SqlConnectionColumnEncryptionSetting)value;
808 else if (value.GetType().IsEnum) {
809 // explicitly block scenarios in which user tries to use wrong enum types, like:
810 // builder["SqlConnectionColumnEncryptionSetting"] = EnvironmentVariableTarget.Process;
811 // workaround: explicitly cast non-SqlConnectionColumnEncryptionSetting enums to int
812 throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionColumnEncryptionSetting), null);
816 // Enum.ToObject allows only integral and enum values (enums are blocked above), rasing ArgumentException for the rest
817 eValue = (SqlConnectionColumnEncryptionSetting)Enum.ToObject(typeof(SqlConnectionColumnEncryptionSetting), value);
819 catch (ArgumentException e) {
820 // to be consistent with the messages we send in case of wrong type usage, replace
821 // the error with our exception, and keep the original one as inner one for troubleshooting
822 throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionColumnEncryptionSetting), e);
826 // ensure value is in valid range
827 if (IsValidColumnEncryptionSetting(eValue)) {
831 throw ADP.InvalidEnumerationValue(typeof(SqlConnectionColumnEncryptionSetting), (int)eValue);
837 internal static class DbConnectionStringDefaults {
839 // internal const string NamedConnection = "";
842 internal const string Driver = "";
843 internal const string Dsn = "";
846 internal const bool AdoNetPooler = false;
847 internal const string FileName = "";
848 internal const int OleDbServices = ~(/*DBPROPVAL_OS_AGR_AFTERSESSION*/0x00000008 | /*DBPROPVAL_OS_CLIENTCURSOR*/0x00000004); // -13
849 internal const string Provider = "";
852 internal const bool Unicode = false;
853 internal const bool OmitOracleConnectionName = false;
856 internal const ApplicationIntent ApplicationIntent = System.Data.SqlClient.ApplicationIntent.ReadWrite;
857 internal const string ApplicationName = ".Net SqlClient Data Provider";
858 internal const bool AsynchronousProcessing = false;
859 internal const string AttachDBFilename = "";
860 internal const int ConnectTimeout = 15;
861 internal const bool ConnectionReset = true;
862 internal const bool ContextConnection = false;
863 internal const string CurrentLanguage = "";
864 internal const string DataSource = "";
865 internal const bool Encrypt = false;
866 internal const bool Enlist = true;
867 internal const string FailoverPartner = "";
868 internal const string InitialCatalog = "";
869 internal const bool IntegratedSecurity = false;
870 internal const int LoadBalanceTimeout = 0; // default of 0 means don't use
871 internal const bool MultipleActiveResultSets = false;
872 internal const bool MultiSubnetFailover = false;
873 internal const bool TransparentNetworkIPResolution = true;
874 internal const int MaxPoolSize = 100;
875 internal const int MinPoolSize = 0;
876 internal const string NetworkLibrary = "";
877 internal const int PacketSize = 8000;
878 internal const string Password = "";
879 internal const bool PersistSecurityInfo = false;
880 internal const bool Pooling = true;
881 internal const bool TrustServerCertificate = false;
882 internal const string TypeSystemVersion = "Latest";
883 internal const string UserID = "";
884 internal const bool UserInstance = false;
885 internal const bool Replication = false;
886 internal const string WorkstationID = "";
887 internal const string TransactionBinding = "Implicit Unbind";
888 internal const int ConnectRetryCount = 1;
889 internal const int ConnectRetryInterval = 10;
890 internal static readonly SqlAuthenticationMethod Authentication = SqlAuthenticationMethod.NotSpecified;
891 internal static readonly SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled;
892 internal const PoolBlockingPeriod PoolBlockingPeriod = SqlClient.PoolBlockingPeriod.Auto;
895 internal static class DbConnectionOptionKeywords {
897 internal const string Driver = "driver";
898 internal const string Pwd = "pwd";
899 internal const string UID = "uid";
902 internal const string DataProvider = "data provider";
903 internal const string ExtendedProperties = "extended properties";
904 internal const string FileName = "file name";
905 internal const string Provider = "provider";
906 internal const string RemoteProvider = "remote provider";
908 // common keywords (OleDb, OracleClient, SqlClient)
909 internal const string Password = "password";
910 internal const string UserID = "user id";
913 internal static class DbConnectionStringKeywords {
915 // internal const string NamedConnection = "Named Connection";
918 internal const string Driver = "Driver";
919 internal const string Dsn = "Dsn";
920 internal const string FileDsn = "FileDsn";
921 internal const string SaveFile = "SaveFile";
924 internal const string FileName = "File Name";
925 internal const string OleDbServices = "OLE DB Services";
926 internal const string Provider = "Provider";
929 internal const string Unicode = "Unicode";
930 internal const string OmitOracleConnectionName = "Omit Oracle Connection Name";
933 internal const string ApplicationIntent = "ApplicationIntent";
934 internal const string ApplicationName = "Application Name";
935 internal const string AsynchronousProcessing = "Asynchronous Processing";
936 internal const string AttachDBFilename = "AttachDbFilename";
937 internal const string ConnectTimeout = "Connect Timeout";
938 internal const string ConnectionReset = "Connection Reset";
939 internal const string ContextConnection = "Context Connection";
940 internal const string CurrentLanguage = "Current Language";
941 internal const string Encrypt = "Encrypt";
942 internal const string FailoverPartner = "Failover Partner";
943 internal const string InitialCatalog = "Initial Catalog";
944 internal const string MultipleActiveResultSets = "MultipleActiveResultSets";
945 internal const string MultiSubnetFailover = "MultiSubnetFailover";
946 internal const string TransparentNetworkIPResolution = "TransparentNetworkIPResolution";
947 internal const string NetworkLibrary = "Network Library";
948 internal const string PacketSize = "Packet Size";
949 internal const string Replication = "Replication";
950 internal const string TransactionBinding = "Transaction Binding";
951 internal const string TrustServerCertificate = "TrustServerCertificate";
952 internal const string TypeSystemVersion = "Type System Version";
953 internal const string UserInstance = "User Instance";
954 internal const string WorkstationID = "Workstation ID";
955 internal const string ConnectRetryCount = "ConnectRetryCount";
956 internal const string ConnectRetryInterval = "ConnectRetryInterval";
957 internal const string Authentication = "Authentication";
958 internal const string Certificate = "Certificate";
959 internal const string ColumnEncryptionSetting = "Column Encryption Setting";
960 internal const string PoolBlockingPeriod = "PoolBlockingPeriod";
962 // common keywords (OleDb, OracleClient, SqlClient)
963 internal const string DataSource = "Data Source";
964 internal const string IntegratedSecurity = "Integrated Security";
965 internal const string Password = "Password";
966 internal const string PersistSecurityInfo = "Persist Security Info";
967 internal const string UserID = "User ID";
969 // managed pooling (OracleClient, SqlClient)
970 internal const string Enlist = "Enlist";
971 internal const string LoadBalanceTimeout = "Load Balance Timeout";
972 internal const string MaxPoolSize = "Max Pool Size";
973 internal const string Pooling = "Pooling";
974 internal const string MinPoolSize = "Min Pool Size";
977 internal static class DbConnectionStringSynonyms {
978 //internal const string AsynchronousProcessing = Async;
979 internal const string Async = "async";
981 //internal const string ApplicationName = APP;
982 internal const string APP = "app";
984 //internal const string AttachDBFilename = EXTENDEDPROPERTIES+","+INITIALFILENAME;
985 internal const string EXTENDEDPROPERTIES = "extended properties";
986 internal const string INITIALFILENAME = "initial file name";
988 //internal const string ConnectTimeout = CONNECTIONTIMEOUT+","+TIMEOUT;
989 internal const string CONNECTIONTIMEOUT = "connection timeout";
990 internal const string TIMEOUT = "timeout";
992 //internal const string CurrentLanguage = LANGUAGE;
993 internal const string LANGUAGE = "language";
995 //internal const string OraDataSource = SERVER;
996 //internal const string SqlDataSource = ADDR+","+ADDRESS+","+SERVER+","+NETWORKADDRESS;
997 internal const string ADDR = "addr";
998 internal const string ADDRESS = "address";
999 internal const string SERVER = "server";
1000 internal const string NETWORKADDRESS = "network address";
1002 //internal const string InitialCatalog = DATABASE;
1003 internal const string DATABASE = "database";
1005 //internal const string IntegratedSecurity = TRUSTEDCONNECTION;
1006 internal const string TRUSTEDCONNECTION = "trusted_connection"; // underscore introduced in everett
1008 //internal const string LoadBalanceTimeout = ConnectionLifetime;
1009 internal const string ConnectionLifetime = "connection lifetime";
1011 //internal const string NetworkLibrary = NET+","+NETWORK;
1012 internal const string NET = "net";
1013 internal const string NETWORK = "network";
1015 internal const string WorkaroundOracleBug914652 = "Workaround Oracle Bug 914652";
1017 //internal const string Password = Pwd;
1018 internal const string Pwd = "pwd";
1020 //internal const string PersistSecurityInfo = PERSISTSECURITYINFO;
1021 internal const string PERSISTSECURITYINFO = "persistsecurityinfo";
1023 //internal const string UserID = UID+","+User;
1024 internal const string UID = "uid";
1025 internal const string User = "user";
1027 //internal const string WorkstationID = WSID;
1028 internal const string WSID = "wsid";