OdbcConnectionStringbuilder.cs 14 KB

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