Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data / System / Data / Odbc / OdbcConnectionStringbuilder.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="OdbcConnectionStringBuilder.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</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
21 namespace System.Data.Odbc {
22
23     [DefaultProperty("Driver")]
24     [System.ComponentModel.TypeConverterAttribute(typeof(OdbcConnectionStringBuilder.OdbcConnectionStringBuilderConverter))]
25     public sealed class OdbcConnectionStringBuilder : DbConnectionStringBuilder {
26
27         private enum Keywords { // must maintain same ordering as _validKeywords array
28 //            NamedConnection,
29             Dsn,
30
31             Driver,
32         }
33
34         private static readonly string[] _validKeywords;
35         private static readonly Dictionary<string,Keywords> _keywords;
36
37         private string[] _knownKeywords;
38
39         private string _dsn    = DbConnectionStringDefaults.Dsn;
40 //        private string _namedConnection  = DbConnectionStringDefaults.NamedConnection;
41
42         private string _driver = DbConnectionStringDefaults.Driver;
43
44         static OdbcConnectionStringBuilder() {
45             string[] validKeywords = new string[2];
46             validKeywords[(int)Keywords.Driver]          = DbConnectionStringKeywords.Driver;
47             validKeywords[(int)Keywords.Dsn]             = DbConnectionStringKeywords.Dsn;
48 //            validKeywords[(int)Keywords.NamedConnection] = DbConnectionStringKeywords.NamedConnection;
49             _validKeywords = validKeywords;
50
51             Dictionary<string,Keywords> hash = new Dictionary<string,Keywords>(2, StringComparer.OrdinalIgnoreCase);
52             hash.Add(DbConnectionStringKeywords.Driver,          Keywords.Driver);
53             hash.Add(DbConnectionStringKeywords.Dsn,             Keywords.Dsn);
54 //            hash.Add(DbConnectionStringKeywords.NamedConnection, Keywords.NamedConnection);
55             Debug.Assert(2 == hash.Count, "initial expected size is incorrect");
56             _keywords = hash;
57         }
58
59         public OdbcConnectionStringBuilder() : this((string)null) {
60         }
61
62         public OdbcConnectionStringBuilder(string connectionString) : base(true) {
63             if (!ADP.IsEmpty(connectionString)) {
64                 ConnectionString = connectionString;
65             }
66         }
67
68         public override object this[string keyword] {
69             get {
70                 ADP.CheckArgumentNull(keyword, "keyword");
71                 Keywords index;
72                 if (_keywords.TryGetValue(keyword, out index)) {
73                     return GetAt(index);
74                 }
75                 else {
76                     return base[keyword];
77                 }
78             }
79             set {
80                 ADP.CheckArgumentNull(keyword, "keyword");
81                 if (null != value) {
82                     Keywords index;
83                     if (_keywords.TryGetValue(keyword, out index)) {
84                         switch(index) {
85                         case Keywords.Driver:          Driver = ConvertToString(value); break;
86                         case Keywords.Dsn:             Dsn = ConvertToString(value); break;
87 //                      case Keywords.NamedConnection: NamedConnection = ConvertToString(value); break;
88                         default:
89                             Debug.Assert(false, "unexpected keyword");
90                             throw ADP.KeywordNotSupported(keyword);
91                         }
92                     }
93                     else {
94                         base[keyword] = value;
95                         ClearPropertyDescriptors();
96                         _knownKeywords = null;
97                     }
98                 }
99                 else {
100                     Remove(keyword);
101                 }
102             }
103         }
104
105         [DisplayName(DbConnectionStringKeywords.Driver)]
106         [ResCategoryAttribute(Res.DataCategory_Source)]
107         [ResDescriptionAttribute(Res.DbConnectionString_Driver)]
108         [RefreshPropertiesAttribute(RefreshProperties.All)]
109         public string Driver {
110             get { return _driver; }
111             set {
112                 SetValue(DbConnectionStringKeywords.Driver, value);
113                 _driver = value;
114             }
115         }
116
117         [DisplayName(DbConnectionStringKeywords.Dsn)]
118         [ResCategoryAttribute(Res.DataCategory_NamedConnectionString)]
119         [ResDescriptionAttribute(Res.DbConnectionString_DSN)]
120         [RefreshPropertiesAttribute(RefreshProperties.All)]
121         public string Dsn {
122             get { return _dsn; }
123             set {
124                 SetValue(DbConnectionStringKeywords.Dsn, value);
125                 _dsn = value;
126             }
127         }
128 /*
129         [DisplayName(DbConnectionStringKeywords.NamedConnection)]
130         [ResCategoryAttribute(Res.DataCategory_NamedConnectionString)]
131         [ResDescriptionAttribute(Res.DbConnectionString_NamedConnection)]
132         [RefreshPropertiesAttribute(RefreshProperties.All)]
133         [TypeConverter(typeof(NamedConnectionStringConverter))]
134         public string NamedConnection {
135             get { return _namedConnection; }
136             set {
137                 SetValue(DbConnectionStringKeywords.NamedConnection, value);
138                 _namedConnection = value;
139             }
140         }
141 */
142         public override ICollection Keys {
143             get {
144                 string[] knownKeywords = _knownKeywords;
145                 if (null == knownKeywords) {
146                     knownKeywords = _validKeywords;
147
148                     int count = 0;
149                     foreach(string keyword in base.Keys) {
150                         bool flag = true;
151                         foreach(string s in knownKeywords) {
152                             if (s == keyword) {
153                                 flag = false;
154                                 break;
155                             }
156                         }
157                         if (flag) {
158                             count++;
159                         }
160                     }
161                     if (0 < count) {
162                         string[] tmp = new string[knownKeywords.Length + count];
163                         knownKeywords.CopyTo(tmp, 0);
164
165                         int index = knownKeywords.Length;
166                         foreach(string keyword in base.Keys) {
167                             bool flag = true;
168                             foreach(string s in knownKeywords) {
169                                 if (s == keyword) {
170                                     flag = false;
171                                     break;
172                                 }
173                             }
174                             if (flag) {
175                                 tmp[index++] = keyword;
176                             }
177                         }
178                         knownKeywords = tmp;
179                     }
180                     _knownKeywords = knownKeywords;
181                 }
182                 return new System.Data.Common.ReadOnlyCollection<string>(knownKeywords);
183             }
184         }
185
186         public override void Clear() {
187             base.Clear();
188             for(int i = 0; i < _validKeywords.Length; ++i) {
189                 Reset((Keywords)i);
190             }
191             _knownKeywords = _validKeywords;
192         }
193
194         public override bool ContainsKey(string keyword) {
195             ADP.CheckArgumentNull(keyword, "keyword");
196             return _keywords.ContainsKey(keyword) || base.ContainsKey(keyword);
197         }
198
199         private static string ConvertToString(object value) {
200             return DbConnectionStringBuilderUtil.ConvertToString(value);
201         }
202
203         private object GetAt(Keywords index) {
204             switch(index) {
205             case Keywords.Driver:          return Driver;
206             case Keywords.Dsn:             return Dsn;
207 //          case Keywords.NamedConnection: return NamedConnection;
208             default:
209             Debug.Assert(false, "unexpected keyword");
210             throw ADP.KeywordNotSupported(_validKeywords[(int)index]);
211             }
212         }
213
214         /*
215         protected override void GetProperties(Hashtable propertyDescriptors) {
216             object value;
217             if (TryGetValue(DbConnectionStringSynonyms.TRUSTEDCONNECTION, out value)) {
218                 bool trusted = false;
219                 if (value is bool) {
220                     trusted = (bool)value;
221                 }
222                 else if ((value is string) && !Boolean.TryParse((string)value, out trusted)) {
223                     trusted = false;
224                 }
225
226                 if (trusted) {
227                    Attribute[] attributes = new Attribute[] {
228                         BrowsableAttribute.Yes,
229                         RefreshPropertiesAttribute.All,
230                     };
231                     DbConnectionStringBuilderDescriptor descriptor;
232                     descriptor = new DbConnectionStringBuilderDescriptor(DbConnectionStringSynonyms.TRUSTEDCONNECTION,
233                                         this.GetType(), typeof(bool), false, attributes);
234                     descriptor.RefreshOnChange = true;
235                     propertyDescriptors[DbConnectionStringSynonyms.TRUSTEDCONNECTION] = descriptor;
236
237                     if (ContainsKey(DbConnectionStringSynonyms.Pwd)) {
238                         descriptor = new DbConnectionStringBuilderDescriptor(DbConnectionStringSynonyms.Pwd,
239                                             this.GetType(), typeof(string), true, attributes);
240                         propertyDescriptors[DbConnectionStringSynonyms.Pwd] = descriptor;
241                     }
242                     if (ContainsKey(DbConnectionStringSynonyms.UID)) {
243                         descriptor = new DbConnectionStringBuilderDescriptor(DbConnectionStringSynonyms.UID,
244                                             this.GetType(), typeof(string), true, attributes);
245                         propertyDescriptors[DbConnectionStringSynonyms.UID] = descriptor;
246                     }
247                 }
248             }
249             base.GetProperties(propertyDescriptors);
250         }
251         */
252
253         public override bool Remove(string keyword) {
254             ADP.CheckArgumentNull(keyword, "keyword");
255             if (base.Remove(keyword)) {
256                 Keywords index;
257                 if (_keywords.TryGetValue(keyword, out index)) {
258                     Reset(index);
259                 }
260                 else {
261                     ClearPropertyDescriptors();
262                     _knownKeywords = null;
263                 }
264                 return true;
265             }
266             return false;
267         }
268         private void Reset(Keywords index) {
269             switch(index) {
270             case Keywords.Driver:
271                 _driver = DbConnectionStringDefaults.Driver;
272                 break;
273             case Keywords.Dsn:
274                 _dsn = DbConnectionStringDefaults.Dsn;
275                 break;
276 //            case Keywords.NamedConnection:
277 //               _namedConnection = DbConnectionStringDefaults.NamedConnection;
278 //                break;
279             default:
280             Debug.Assert(false, "unexpected keyword");
281             throw ADP.KeywordNotSupported(_validKeywords[(int)index]);
282             }
283         }
284
285         private void SetValue(string keyword, string value) {
286             ADP.CheckArgumentNull(value, keyword);
287             base[keyword] = value;
288         }
289
290         public override bool TryGetValue(string keyword, out object value) {
291             ADP.CheckArgumentNull(keyword, "keyword");
292             Keywords index;
293             if (_keywords.TryGetValue(keyword, out index)) {
294                 value = GetAt(index);
295                 return true;
296             }
297             return base.TryGetValue(keyword, out value);
298         }
299
300         sealed internal class OdbcConnectionStringBuilderConverter : ExpandableObjectConverter {
301
302             // converter classes should have public ctor
303             public OdbcConnectionStringBuilderConverter() {
304             }
305
306             override public bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
307                 if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) {
308                     return true;
309                 }
310                 return base.CanConvertTo(context, destinationType);
311             }
312
313             override public object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
314                 if (destinationType == null) {
315                     throw ADP.ArgumentNull("destinationType");
316                 }
317                 if (typeof(System.ComponentModel.Design.Serialization.InstanceDescriptor) == destinationType) {
318                     OdbcConnectionStringBuilder obj = (value as OdbcConnectionStringBuilder);
319                     if (null != obj) {
320                         return ConvertToInstanceDescriptor(obj);
321                     }
322                 }
323                 return base.ConvertTo(context, culture, value, destinationType);
324             }
325
326             private System.ComponentModel.Design.Serialization.InstanceDescriptor ConvertToInstanceDescriptor(OdbcConnectionStringBuilder options) {
327                 Type[] ctorParams = new Type[] { typeof(string) };
328                 object[] ctorValues = new object[] { options.ConnectionString };
329                 System.Reflection.ConstructorInfo ctor = typeof(OdbcConnectionStringBuilder).GetConstructor(ctorParams);
330                 return new System.ComponentModel.Design.Serialization.InstanceDescriptor(ctor, ctorValues);
331             }
332         }
333     }
334 }