Moving BSTR conv to native code in SecureStringToBSTR.
[mono.git] / mcs / class / referencesource / System.Data / System / Data / Common / DbConnectionStringCommon.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="DbConnectionStringBuilder.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">[....]</owner>
6 // <owner current="true" primary="false">[....]</owner>
7 //------------------------------------------------------------------------------
8
9     using System;
10     using System.Collections;
11     using System.Collections.Generic;
12     using System.ComponentModel;
13     using System.Data;
14     using System.Data.Common;
15     using System.Diagnostics;
16     using System.Globalization;
17     using System.Runtime.Serialization;
18     using System.Security.Permissions;
19     using System.Text;
20     using System.Text.RegularExpressions;
21 using System.Data.SqlClient;
22
23 namespace System.Data.Common {
24
25 /*
26     internal sealed class NamedConnectionStringConverter : StringConverter {
27
28         public NamedConnectionStringConverter() {
29         }
30
31         public override bool GetStandardValuesSupported(ITypeDescriptorContext context) {
32             return true;
33         }
34
35         public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) {
36             // Although theoretically this could be true, some people may want to just type in a name
37             return false;
38         }
39
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;
46
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);
51                         }
52                     }
53                     standardValues = new StandardValuesCollection(myConnectionNames);
54                 }
55             }
56             return standardValues;
57         }
58     }
59 */
60
61     internal class DbConnectionStringBuilderDescriptor : PropertyDescriptor {
62         private Type _componentType;
63         private Type _propertyType;
64         private bool _isReadOnly;
65         private bool _refreshOnChange;
66
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;
72         }
73
74         internal bool RefreshOnChange {
75             get {
76                 return _refreshOnChange;
77             }
78             set {
79                 _refreshOnChange = value;
80             }
81         }
82
83         public override Type ComponentType {
84             get {
85                 return _componentType;
86             }
87         }
88         public override bool IsReadOnly {
89             get {
90                 return _isReadOnly;
91             }
92         }
93         public override Type PropertyType {
94             get {
95                 return _propertyType;
96             }
97         }
98         public override bool CanResetValue(object component) {
99             DbConnectionStringBuilder builder = (component as DbConnectionStringBuilder);
100             return ((null != builder) && builder.ShouldSerialize(DisplayName));
101         }
102         public override object GetValue(object component) {
103             DbConnectionStringBuilder builder = (component as DbConnectionStringBuilder);
104             if (null != builder) {
105                 object value;
106                 if (builder.TryGetValue(DisplayName, out value)) {
107                     return value;
108                 }
109             }
110             return null;
111         }
112         public override void ResetValue(object component) {
113             DbConnectionStringBuilder builder = (component as DbConnectionStringBuilder);
114             if (null != builder) {
115                 builder.Remove(DisplayName);
116
117                 if (RefreshOnChange) {
118                     builder.ClearPropertyDescriptors();
119                 }
120             }
121         }
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)) {
127                     value = null;
128                 }
129                 builder[DisplayName] = value;
130
131                 if (RefreshOnChange) {
132                     builder.ClearPropertyDescriptors();
133                 }
134             }
135         }
136         public override bool ShouldSerializeValue(object component) {
137             DbConnectionStringBuilder builder = (component as DbConnectionStringBuilder);
138             return ((null != builder) && builder.ShouldSerialize(DisplayName));
139         }
140     }
141
142     [Serializable()]
143     internal sealed class ReadOnlyCollection<T> : System.Collections.ICollection, ICollection<T> {
144         private T[] _items;
145
146         internal ReadOnlyCollection(T[] items) {
147             _items = items;
148 #if DEBUG
149             for(int i = 0; i < items.Length; ++i) {
150                 Debug.Assert(null != items[i], "null item");
151             }
152 #endif
153         }
154
155         public void CopyTo(T[] array, int arrayIndex) {
156             Array.Copy(_items, 0, array, arrayIndex, _items.Length);
157         }
158
159         void System.Collections.ICollection.CopyTo(Array array, int arrayIndex) {
160             Array.Copy(_items, 0, array, arrayIndex, _items.Length);
161         }
162
163
164         IEnumerator<T> IEnumerable<T>.GetEnumerator() {
165             return new Enumerator<T>(_items);
166         }
167
168         public System.Collections.IEnumerator GetEnumerator() {
169             return new Enumerator<T>(_items);
170         }
171
172         bool System.Collections.ICollection.IsSynchronized {
173             get { return false; }
174         }
175
176         Object System.Collections.ICollection.SyncRoot {
177             get { return _items; }
178         }
179
180         bool ICollection<T>.IsReadOnly {
181             get { return true;}
182         }
183
184         void ICollection<T>.Add(T value) {
185             throw new NotSupportedException();
186         }
187
188         void ICollection<T>.Clear() {
189             throw new NotSupportedException();
190         }
191
192         bool ICollection<T>.Contains(T value) {
193             return Array.IndexOf(_items, value) >= 0;
194         }
195
196         bool ICollection<T>.Remove(T value) {
197             throw new NotSupportedException();
198         }
199
200         public int Count {
201             get { return _items.Length; }
202         }
203
204         [Serializable()]
205         internal struct Enumerator<K> : IEnumerator<K>, System.Collections.IEnumerator { // based on List<T>.Enumerator
206             private K[] _items;
207             private int _index;
208
209             internal Enumerator(K[] items) {
210                 _items = items;
211                 _index = -1;
212             }
213
214             public void Dispose() {
215             }
216
217             public bool MoveNext() {
218                 return (++_index < _items.Length);
219             }
220
221             public K Current {
222                 get {
223                     return _items[_index];
224                 }
225             }
226
227             Object System.Collections.IEnumerator.Current {
228                 get {
229                     return _items[_index];
230                 }
231             }
232
233             void System.Collections.IEnumerator.Reset() {
234                 _index = -1;
235             }
236         }
237     }
238
239     internal static class DbConnectionStringBuilderUtil
240     {
241
242         internal static bool ConvertToBoolean(object value)
243         {
244             Debug.Assert(null != value, "ConvertToBoolean(null)");
245             string svalue = (value as string);
246             if (null != svalue)
247             {
248                 if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes"))
249                     return true;
250                 else if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "false") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "no"))
251                     return false;
252                 else
253                 {
254                     string tmp = svalue.Trim();  // Remove leading & trailing white space.
255                     if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "true") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "yes"))
256                         return true;
257                     else if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "false") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "no"))
258                         return false;
259                 }
260                 return Boolean.Parse(svalue);
261             }
262             try
263             {
264                 return ((IConvertible)value).ToBoolean(CultureInfo.InvariantCulture);
265             }
266             catch (InvalidCastException e)
267             {
268                 throw ADP.ConvertFailed(value.GetType(), typeof(Boolean), e);
269             }
270         }
271
272         internal static bool ConvertToIntegratedSecurity(object value)
273         {
274             Debug.Assert(null != value, "ConvertToIntegratedSecurity(null)");
275             string svalue = (value as string);
276             if (null != svalue)
277             {
278                 if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "sspi") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "true") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "yes"))
279                     return true;
280                 else if (StringComparer.OrdinalIgnoreCase.Equals(svalue, "false") || StringComparer.OrdinalIgnoreCase.Equals(svalue, "no"))
281                     return false;
282                 else
283                 {
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"))
286                         return true;
287                     else if (StringComparer.OrdinalIgnoreCase.Equals(tmp, "false") || StringComparer.OrdinalIgnoreCase.Equals(tmp, "no"))
288                         return false;
289                 }
290                 return Boolean.Parse(svalue);
291             }
292             try
293             {
294                 return ((IConvertible)value).ToBoolean(CultureInfo.InvariantCulture);
295             }
296             catch (InvalidCastException e)
297             {
298                 throw ADP.ConvertFailed(value.GetType(), typeof(Boolean), e);
299             }
300         }
301
302         internal static int ConvertToInt32(object value)
303         {
304             try
305             {
306                 return ((IConvertible)value).ToInt32(CultureInfo.InvariantCulture);
307             }
308             catch (InvalidCastException e)
309             {
310                 throw ADP.ConvertFailed(value.GetType(), typeof(Int32), e);
311             }
312         }
313
314         internal static string ConvertToString(object value)
315         {
316             try
317             {
318                 return ((IConvertible)value).ToString(CultureInfo.InvariantCulture);
319             }
320             catch (InvalidCastException e)
321             {
322                 throw ADP.ConvertFailed(value.GetType(), typeof(String), e);
323             }
324         }
325
326         const string ApplicationIntentReadWriteString = "ReadWrite";
327         const string ApplicationIntentReadOnlyString = "ReadOnly";
328
329         internal static bool TryConvertToApplicationIntent(string value, out ApplicationIntent result)
330         {
331             Debug.Assert(Enum.GetNames(typeof(ApplicationIntent)).Length == 2, "ApplicationIntent enum has changed, update needed");
332             Debug.Assert(null != value, "TryConvertToApplicationIntent(null,...)");
333
334             if (StringComparer.OrdinalIgnoreCase.Equals(value, ApplicationIntentReadOnlyString))
335             {
336                 result = ApplicationIntent.ReadOnly;
337                 return true;
338             }
339             else if (StringComparer.OrdinalIgnoreCase.Equals(value, ApplicationIntentReadWriteString))
340             {
341                 result = ApplicationIntent.ReadWrite;
342                 return true;
343             }
344             else
345             {
346                 result = DbConnectionStringDefaults.ApplicationIntent;
347                 return false;
348             }
349         }
350
351         internal static bool IsValidApplicationIntentValue(ApplicationIntent value)
352         {
353             Debug.Assert(Enum.GetNames(typeof(ApplicationIntent)).Length == 2, "ApplicationIntent enum has changed, update needed");
354             return value == ApplicationIntent.ReadOnly || value == ApplicationIntent.ReadWrite;
355         }
356
357         internal static string ApplicationIntentToString(ApplicationIntent value)
358         {
359             Debug.Assert(IsValidApplicationIntentValue(value));
360             if (value == ApplicationIntent.ReadOnly)
361             {
362                 return ApplicationIntentReadOnlyString;
363             }
364             else
365             {
366                 return ApplicationIntentReadWriteString;
367             }
368         }
369
370         /// <summary>
371         /// This method attempts to convert the given value tp ApplicationIntent enum. The algorithm is:
372         /// * if the value is from type string, it will be matched against ApplicationIntent enum names only, using ordinal, case-insensitive comparer
373         /// * if the value is from type ApplicationIntent, it will be used as is
374         /// * if the value is from integral type (SByte, Int16, Int32, Int64, Byte, UInt16, UInt32, or UInt64), it will be converted to enum
375         /// * if the value is another enum or any other type, it will be blocked with an appropriate ArgumentException
376         /// 
377         /// in any case above, if the conerted value is out of valid range, the method raises ArgumentOutOfRangeException.
378         /// </summary>
379         /// <returns>applicaiton intent value in the valid range</returns>
380         internal static ApplicationIntent ConvertToApplicationIntent(string keyword, object value)
381         {
382             Debug.Assert(null != value, "ConvertToApplicationIntent(null)");
383             string sValue = (value as string);
384             ApplicationIntent result;
385             if (null != sValue)
386             {
387                 // We could use Enum.TryParse<ApplicationIntent> here, but it accepts value combinations like
388                 // "ReadOnly, ReadWrite" which are unwelcome here
389                 // Also, Enum.TryParse is 100x slower than plain StringComparer.OrdinalIgnoreCase.Equals method.
390
391                 if (TryConvertToApplicationIntent(sValue, out result))
392                 {
393                     return result;
394                 }
395
396                 // try again after remove leading & trailing whitespaces.
397                 sValue = sValue.Trim();
398                 if (TryConvertToApplicationIntent(sValue, out result))
399                 {
400                     return result;
401                 }
402
403                 // string values must be valid
404                 throw ADP.InvalidConnectionOptionValue(keyword);
405             }
406             else
407             {
408                 // the value is not string, try other options
409                 ApplicationIntent eValue;
410
411                 if (value is ApplicationIntent)
412                 {
413                     // quick path for the most common case
414                     eValue = (ApplicationIntent)value;
415                 }
416                 else if (value.GetType().IsEnum)
417                 {
418                     // explicitly block scenarios in which user tries to use wrong enum types, like:
419                     // builder["ApplicationIntent"] = EnvironmentVariableTarget.Process;
420                     // workaround: explicitly cast non-ApplicationIntent enums to int
421                     throw ADP.ConvertFailed(value.GetType(), typeof(ApplicationIntent), null);
422                 }
423                 else
424                 {
425                     try
426                     {
427                         // Enum.ToObject allows only integral and enum values (enums are blocked above), rasing ArgumentException for the rest
428                         eValue = (ApplicationIntent)Enum.ToObject(typeof(ApplicationIntent), value);
429                     }
430                     catch (ArgumentException e)
431                     {
432                         // to be consistent with the messages we send in case of wrong type usage, replace 
433                         // the error with our exception, and keep the original one as inner one for troubleshooting
434                         throw ADP.ConvertFailed(value.GetType(), typeof(ApplicationIntent), e);
435                     }
436                 }
437
438                 // ensure value is in valid range
439                 if (IsValidApplicationIntentValue(eValue))
440                 {
441                     return eValue;
442                 }
443                 else
444                 {
445                     throw ADP.InvalidEnumerationValue(typeof(ApplicationIntent), (int)eValue);
446                 }
447             }
448         }
449
450         const string SqlPasswordString = "Sql Password";
451         const string ActiveDirectoryPasswordString = "Active Directory Password";
452         const string ActiveDirectoryIntegratedString = "Active Directory Integrated";
453
454         internal static bool TryConvertToAuthenticationType(string value, out SqlAuthenticationMethod result)
455         {
456             Debug.Assert(Enum.GetNames(typeof(SqlAuthenticationMethod)).Length == 4, "SqlAuthenticationMethod enum has changed, update needed");
457
458             bool isSuccess = false;
459
460             if (StringComparer.InvariantCultureIgnoreCase.Equals(value, SqlPasswordString))
461             {
462                 result = SqlAuthenticationMethod.SqlPassword;
463                 isSuccess = true;
464             }
465             else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryPasswordString))
466             {
467                 result = SqlAuthenticationMethod.ActiveDirectoryPassword;
468                 isSuccess = true;
469             }
470             else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ActiveDirectoryIntegratedString))
471             {
472                 result = SqlAuthenticationMethod.ActiveDirectoryIntegrated;
473                 isSuccess = true;
474             }
475             else
476             {
477                 result = DbConnectionStringDefaults.Authentication;
478             }
479             return isSuccess;
480         }
481
482         /// <summary>
483         /// Column Encryption Setting.
484         /// </summary>
485         const string ColumnEncryptionSettingEnabledString = "Enabled";
486         const string ColumnEncryptionSettingDisabledString = "Disabled";
487
488         /// <summary>
489         /// Convert a string value to the corresponding SqlConnectionColumnEncryptionSetting.
490         /// </summary>
491         /// <param name="value"></param>
492         /// <param name="result"></param>
493         /// <returns></returns>
494         internal static bool TryConvertToColumnEncryptionSetting(string value, out SqlConnectionColumnEncryptionSetting result) {
495             bool isSuccess = false;
496
497             if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ColumnEncryptionSettingEnabledString)) {
498                 result = SqlConnectionColumnEncryptionSetting.Enabled;
499                 isSuccess = true;
500             }
501             else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, ColumnEncryptionSettingDisabledString)) {
502                 result = SqlConnectionColumnEncryptionSetting.Disabled;
503                 isSuccess = true;
504             }
505             else {
506                 result = DbConnectionStringDefaults.ColumnEncryptionSetting;
507             }
508
509             return isSuccess;
510         }
511
512         /// <summary>
513         /// Is it a valid connection level column encryption setting ?
514         /// </summary>
515         /// <param name="value"></param>
516         /// <returns></returns>
517         internal static bool IsValidColumnEncryptionSetting(SqlConnectionColumnEncryptionSetting value) {
518             Debug.Assert(Enum.GetNames(typeof(SqlConnectionColumnEncryptionSetting)).Length == 2, "SqlConnectionColumnEncryptionSetting enum has changed, update needed");
519             return value == SqlConnectionColumnEncryptionSetting.Enabled || value == SqlConnectionColumnEncryptionSetting.Disabled;
520         }
521
522         /// <summary>
523         /// Convert connection level column encryption setting value to string.
524         /// </summary>
525         /// <param name="value"></param>
526         /// <returns></returns>
527         internal static string ColumnEncryptionSettingToString(SqlConnectionColumnEncryptionSetting value) {
528             Debug.Assert(IsValidColumnEncryptionSetting(value), "value is not a valid connection level column encryption setting.");
529
530             switch (value) {
531                 case SqlConnectionColumnEncryptionSetting.Enabled:
532                     return ColumnEncryptionSettingEnabledString;
533                 case SqlConnectionColumnEncryptionSetting.Disabled:
534                     return ColumnEncryptionSettingDisabledString;
535
536                 default:
537                     return null;
538             }
539         }
540
541         internal static bool IsValidAuthenticationTypeValue(SqlAuthenticationMethod value) {
542             Debug.Assert(Enum.GetNames(typeof(SqlAuthenticationMethod)).Length == 4, "SqlAuthenticationMethod enum has changed, update needed");
543             return value == SqlAuthenticationMethod.SqlPassword
544                 || value == SqlAuthenticationMethod.ActiveDirectoryPassword
545                 || value == SqlAuthenticationMethod.ActiveDirectoryIntegrated
546                 || value == SqlAuthenticationMethod.NotSpecified;
547         }
548
549         internal static string AuthenticationTypeToString(SqlAuthenticationMethod value)
550         {
551             Debug.Assert(IsValidAuthenticationTypeValue(value));
552
553             switch (value)
554             {
555                 case SqlAuthenticationMethod.SqlPassword:
556                     return SqlPasswordString;
557                 case SqlAuthenticationMethod.ActiveDirectoryPassword:
558                     return ActiveDirectoryPasswordString;
559                 case SqlAuthenticationMethod.ActiveDirectoryIntegrated:
560                     return ActiveDirectoryIntegratedString;
561                 default:
562                     return null;
563             }
564         }
565
566         internal static SqlAuthenticationMethod ConvertToAuthenticationType(string keyword, object value)
567         {
568             if (null == value)
569             {
570                 return DbConnectionStringDefaults.Authentication;
571             }
572
573             string sValue = (value as string);
574             SqlAuthenticationMethod result;
575             if (null != sValue)
576             {
577                 if (TryConvertToAuthenticationType(sValue, out result))
578                 {
579                     return result;
580                 }
581
582                 // try again after remove leading & trailing whitespaces.
583                 sValue = sValue.Trim();
584                 if (TryConvertToAuthenticationType(sValue, out result))
585                 {
586                     return result;
587                 }
588
589                 // string values must be valid
590                 throw ADP.InvalidConnectionOptionValue(keyword);
591             }
592             else
593             {
594                 // the value is not string, try other options
595                 SqlAuthenticationMethod eValue;
596
597                 if (value is SqlAuthenticationMethod)
598                 {
599                     // quick path for the most common case
600                     eValue = (SqlAuthenticationMethod)value;
601                 }
602                 else if (value.GetType().IsEnum)
603                 {
604                     // explicitly block scenarios in which user tries to use wrong enum types, like:
605                     // builder["ApplicationIntent"] = EnvironmentVariableTarget.Process;
606                     // workaround: explicitly cast non-ApplicationIntent enums to int
607                     throw ADP.ConvertFailed(value.GetType(), typeof(SqlAuthenticationMethod), null);
608                 }
609                 else
610                 {
611                     try
612                     {
613                         // Enum.ToObject allows only integral and enum values (enums are blocked above), rasing ArgumentException for the rest
614                         eValue = (SqlAuthenticationMethod)Enum.ToObject(typeof(SqlAuthenticationMethod), value);
615                     }
616                     catch (ArgumentException e)
617                     {
618                         // to be consistent with the messages we send in case of wrong type usage, replace 
619                         // the error with our exception, and keep the original one as inner one for troubleshooting
620                         throw ADP.ConvertFailed(value.GetType(), typeof(SqlAuthenticationMethod), e);
621                     }
622                 }
623
624                 // ensure value is in valid range
625                 if (IsValidAuthenticationTypeValue(eValue))
626                 {
627                     return eValue;
628                 }
629                 else
630                 {
631                     throw ADP.InvalidEnumerationValue(typeof(SqlAuthenticationMethod), (int)eValue);
632                 }
633             }
634         }
635
636         /// <summary>
637         /// Convert the provided value to a SqlConnectionColumnEncryptionSetting.
638         /// </summary>
639         /// <param name="keyword"></param>
640         /// <param name="value"></param>
641         /// <returns></returns>
642         internal static SqlConnectionColumnEncryptionSetting ConvertToColumnEncryptionSetting(string keyword, object value) {
643             if (null == value) {
644                 return DbConnectionStringDefaults.ColumnEncryptionSetting;
645             }
646
647             string sValue = (value as string);
648             SqlConnectionColumnEncryptionSetting result;
649             if (null != sValue) {
650                 if (TryConvertToColumnEncryptionSetting(sValue, out result)) {
651                     return result;
652                 }
653
654                 // try again after remove leading & trailing whitespaces.
655                 sValue = sValue.Trim();
656                 if (TryConvertToColumnEncryptionSetting(sValue, out result)) {
657                     return result;
658                 }
659
660                 // string values must be valid
661                 throw ADP.InvalidConnectionOptionValue(keyword);
662             }
663             else {
664                 // the value is not string, try other options
665                 SqlConnectionColumnEncryptionSetting eValue;
666
667                 if (value is SqlConnectionColumnEncryptionSetting) {
668                     // quick path for the most common case
669                     eValue = (SqlConnectionColumnEncryptionSetting)value;
670                 }
671                 else if (value.GetType().IsEnum) {
672                     // explicitly block scenarios in which user tries to use wrong enum types, like:
673                     // builder["SqlConnectionColumnEncryptionSetting"] = EnvironmentVariableTarget.Process;
674                     // workaround: explicitly cast non-SqlConnectionColumnEncryptionSetting enums to int
675                     throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionColumnEncryptionSetting), null);
676                 }
677                 else {
678                     try {
679                         // Enum.ToObject allows only integral and enum values (enums are blocked above), rasing ArgumentException for the rest
680                         eValue = (SqlConnectionColumnEncryptionSetting)Enum.ToObject(typeof(SqlConnectionColumnEncryptionSetting), value);
681                     }
682                     catch (ArgumentException e) {
683                         // to be consistent with the messages we send in case of wrong type usage, replace 
684                         // the error with our exception, and keep the original one as inner one for troubleshooting
685                         throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionColumnEncryptionSetting), e);
686                     }
687                 }
688
689                 // ensure value is in valid range
690                 if (IsValidColumnEncryptionSetting(eValue)) {
691                     return eValue;
692                 }
693                 else {
694                     throw ADP.InvalidEnumerationValue(typeof(SqlConnectionColumnEncryptionSetting), (int)eValue);
695                 }
696             }
697         }
698     }
699
700     internal static class DbConnectionStringDefaults {
701         // all
702 //        internal const string NamedConnection           = "";
703
704         // Odbc
705         internal const string Driver                    = "";
706         internal const string Dsn                       = "";
707
708         // OleDb
709         internal const bool   AdoNetPooler              = false;
710         internal const string FileName                  = "";
711         internal const int    OleDbServices             = ~(/*DBPROPVAL_OS_AGR_AFTERSESSION*/0x00000008 | /*DBPROPVAL_OS_CLIENTCURSOR*/0x00000004); // -13
712         internal const string Provider                  = "";
713
714         // OracleClient
715         internal const bool   Unicode                   = false;
716         internal const bool   OmitOracleConnectionName  = false;
717
718         // SqlClient
719         internal const ApplicationIntent ApplicationIntent   = System.Data.SqlClient.ApplicationIntent.ReadWrite;
720                 internal const string ApplicationName                = ".Net SqlClient Data Provider";
721                 internal const bool   AsynchronousProcessing         = false;
722                 internal const string AttachDBFilename               = "";
723                 internal const int    ConnectTimeout                 = 15;
724                 internal const bool   ConnectionReset                = true;
725                 internal const bool   ContextConnection              = false;
726                 internal const string CurrentLanguage                = "";
727                 internal const string DataSource                     = "";
728                 internal const bool   Encrypt                        = false;
729                 internal const bool   Enlist                         = true;
730                 internal const string FailoverPartner                = "";
731                 internal const string InitialCatalog                 = "";
732                 internal const bool   IntegratedSecurity             = false;
733                 internal const int    LoadBalanceTimeout             = 0; // default of 0 means don't use
734                 internal const bool   MultipleActiveResultSets       = false;
735                 internal const bool   MultiSubnetFailover            = false;
736                 internal const bool   TransparentNetworkIPResolution = true;
737                 internal const int    MaxPoolSize                    = 100;
738                 internal const int    MinPoolSize                    = 0;
739                 internal const string NetworkLibrary                 = "";
740                 internal const int    PacketSize                     = 8000;
741                 internal const string Password                       =  "";
742                 internal const bool   PersistSecurityInfo            = false;
743                 internal const bool   Pooling                        = true;
744                 internal const bool   TrustServerCertificate         = false;
745                 internal const string TypeSystemVersion              = "Latest";
746                 internal const string UserID                         = "";
747                 internal const bool   UserInstance                   = false;
748                 internal const bool   Replication                    = false;
749                 internal const string WorkstationID                  = "";
750                 internal const string TransactionBinding             = "Implicit Unbind";
751                 internal const int    ConnectRetryCount              = 1;
752                 internal const int    ConnectRetryInterval           = 10;
753         internal static readonly SqlAuthenticationMethod Authentication = SqlAuthenticationMethod.NotSpecified;
754         internal static readonly SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled;
755     }
756
757     internal static class DbConnectionOptionKeywords {
758         // Odbc
759         internal const string Driver                    = "driver";
760         internal const string Pwd                       = "pwd";
761         internal const string UID                       = "uid";
762
763         // OleDb
764         internal const string DataProvider              = "data provider";
765         internal const string ExtendedProperties        = "extended properties";
766         internal const string FileName                  = "file name";
767         internal const string Provider                  = "provider";
768         internal const string RemoteProvider            = "remote provider";
769
770         // common keywords (OleDb, OracleClient, SqlClient)
771         internal const string Password                  = "password";
772         internal const string UserID                    = "user id";
773     }
774
775     internal static class DbConnectionStringKeywords {
776         // all
777 //        internal const string NamedConnection           = "Named Connection";
778
779         // Odbc
780         internal const string Driver                    = "Driver";
781         internal const string Dsn                       = "Dsn";
782         internal const string FileDsn                   = "FileDsn";
783         internal const string SaveFile                  = "SaveFile";
784
785         // OleDb
786         internal const string FileName                  = "File Name";
787         internal const string OleDbServices             = "OLE DB Services";
788         internal const string Provider                  = "Provider";
789
790         // OracleClient
791         internal const string Unicode                   = "Unicode";
792         internal const string OmitOracleConnectionName  = "Omit Oracle Connection Name";
793
794         // SqlClient
795                 internal const string ApplicationIntent              = "ApplicationIntent";
796                 internal const string ApplicationName                = "Application Name";
797                 internal const string AsynchronousProcessing         = "Asynchronous Processing";
798                 internal const string AttachDBFilename               = "AttachDbFilename";
799                 internal const string ConnectTimeout                 = "Connect Timeout";
800                 internal const string ConnectionReset                = "Connection Reset";
801                 internal const string ContextConnection              = "Context Connection";
802                 internal const string CurrentLanguage                = "Current Language";
803                 internal const string Encrypt                        = "Encrypt";
804                 internal const string FailoverPartner                = "Failover Partner";
805                 internal const string InitialCatalog                 = "Initial Catalog";
806                 internal const string MultipleActiveResultSets       = "MultipleActiveResultSets";
807                 internal const string MultiSubnetFailover            = "MultiSubnetFailover";
808                 internal const string TransparentNetworkIPResolution = "TransparentNetworkIPResolution";
809                 internal const string NetworkLibrary                 = "Network Library";
810                 internal const string PacketSize                     = "Packet Size";
811                 internal const string Replication                    = "Replication";
812                 internal const string TransactionBinding             = "Transaction Binding";
813                 internal const string TrustServerCertificate         = "TrustServerCertificate";
814                 internal const string TypeSystemVersion              = "Type System Version";
815                 internal const string UserInstance                   = "User Instance";
816                 internal const string WorkstationID                  = "Workstation ID";
817                 internal const string ConnectRetryCount              = "ConnectRetryCount";
818                 internal const string ConnectRetryInterval           = "ConnectRetryInterval";
819                 internal const string Authentication                 = "Authentication";
820                 internal const string Certificate                    = "Certificate";
821                 internal const string ColumnEncryptionSetting        = "Column Encryption Setting";
822         
823         // common keywords (OleDb, OracleClient, SqlClient)
824         internal const string DataSource                = "Data Source";
825         internal const string IntegratedSecurity        = "Integrated Security";
826         internal const string Password                  = "Password";
827         internal const string PersistSecurityInfo       = "Persist Security Info";
828         internal const string UserID                    = "User ID";
829
830         // managed pooling (OracleClient, SqlClient)
831         internal const string Enlist                    = "Enlist";
832         internal const string LoadBalanceTimeout        = "Load Balance Timeout";
833         internal const string MaxPoolSize               = "Max Pool Size";
834         internal const string Pooling                   = "Pooling";
835         internal const string MinPoolSize               = "Min Pool Size";
836     }
837
838     internal static class DbConnectionStringSynonyms {
839         //internal const string AsynchronousProcessing = Async;
840         internal const string Async                  = "async";
841
842         //internal const string ApplicationName        = APP;
843         internal const string APP                    = "app";
844
845         //internal const string AttachDBFilename       = EXTENDEDPROPERTIES+","+INITIALFILENAME;
846         internal const string EXTENDEDPROPERTIES     = "extended properties";
847         internal const string INITIALFILENAME        = "initial file name";
848
849         //internal const string ConnectTimeout         = CONNECTIONTIMEOUT+","+TIMEOUT;
850         internal const string CONNECTIONTIMEOUT      = "connection timeout";
851         internal const string TIMEOUT                = "timeout";
852
853         //internal const string CurrentLanguage        = LANGUAGE;
854         internal const string LANGUAGE               = "language";
855
856         //internal const string OraDataSource          = SERVER;
857         //internal const string SqlDataSource          = ADDR+","+ADDRESS+","+SERVER+","+NETWORKADDRESS;
858         internal const string ADDR                   = "addr";
859         internal const string ADDRESS                = "address";
860         internal const string SERVER                 = "server";
861         internal const string NETWORKADDRESS         = "network address";
862
863         //internal const string InitialCatalog         = DATABASE;
864         internal const string DATABASE               = "database";
865
866         //internal const string IntegratedSecurity     = TRUSTEDCONNECTION;
867         internal const string TRUSTEDCONNECTION      = "trusted_connection"; // underscore introduced in everett
868
869         //internal const string LoadBalanceTimeout     = ConnectionLifetime;
870         internal const string ConnectionLifetime     = "connection lifetime";
871
872         //internal const string NetworkLibrary         = NET+","+NETWORK;
873         internal const string NET                    = "net";
874         internal const string NETWORK                = "network";
875
876         internal const string WorkaroundOracleBug914652 = "Workaround Oracle Bug 914652";
877
878         //internal const string Password               = Pwd;
879         internal const string Pwd                    = "pwd";
880
881         //internal const string PersistSecurityInfo    = PERSISTSECURITYINFO;
882         internal const string PERSISTSECURITYINFO    = "persistsecurityinfo";
883
884         //internal const string UserID                 = UID+","+User;
885         internal const string UID                    = "uid";
886         internal const string User                   = "user";
887
888         //internal const string WorkstationID          = WSID;
889         internal const string WSID                   = "wsid";
890     }
891 }