You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1238 lines
46 KiB

4 years ago
  1. #if MYSQL_6_9
  2. // Copyright © 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  3. //
  4. // MySQL Connector/NET is licensed under the terms of the GPLv2
  5. // <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
  6. // MySQL Connectors. There are special exceptions to the terms and
  7. // conditions of the GPLv2 as it is applied to this software, see the
  8. // FLOSS License Exception
  9. // <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
  10. //
  11. // This program is free software; you can redistribute it and/or modify
  12. // it under the terms of the GNU General Public License as published
  13. // by the Free Software Foundation; version 2 of the License.
  14. //
  15. // This program is distributed in the hope that it will be useful, but
  16. // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  17. // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  18. // for more details.
  19. //
  20. // You should have received a copy of the GNU General Public License along
  21. // with this program; if not, write to the Free Software Foundation, Inc.,
  22. // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  23. using System;
  24. using System.Collections.Generic;
  25. using System.ComponentModel;
  26. using System.Text.RegularExpressions;
  27. using System.Text;
  28. using System.Globalization;
  29. using System.Reflection;
  30. using Externals.MySql.Data.MySqlClient;
  31. using Externals.MySql.Data.MySqlClient.Properties;
  32. namespace Externals.MySql.Data.MySqlClient
  33. {
  34. internal sealed partial class MySqlConnectionStringBuilder
  35. {
  36. internal Dictionary<string, object> values = new Dictionary<string, object>();
  37. //internal Dictionary<string, object> values
  38. //{
  39. // get { lock (this) { return _values; } }
  40. //}
  41. private static MySqlConnectionStringOptionCollection options = new MySqlConnectionStringOptionCollection();
  42. static MySqlConnectionStringBuilder()
  43. {
  44. // Server options
  45. options.Add(new MySqlConnectionStringOption("server", "host,data source,datasource,address,addr,network address", typeof(string), "" /*"localhost"*/, false));
  46. options.Add(new MySqlConnectionStringOption("database", "initial catalog", typeof(string), string.Empty, false));
  47. options.Add(new MySqlConnectionStringOption("protocol", "connection protocol, connectionprotocol", typeof(MySqlConnectionProtocol), MySqlConnectionProtocol.Sockets, false));
  48. options.Add(new MySqlConnectionStringOption("port", null, typeof(uint), ( uint )3306, false));
  49. options.Add(new MySqlConnectionStringOption("pipe", "pipe name,pipename", typeof(string), "MYSQL", false));
  50. options.Add(new MySqlConnectionStringOption("compress", "use compression,usecompression", typeof(bool), false, false));
  51. options.Add(new MySqlConnectionStringOption("allowbatch", "allow batch", typeof(bool), true, false));
  52. options.Add(new MySqlConnectionStringOption("logging", null, typeof(bool), false, false));
  53. options.Add(new MySqlConnectionStringOption("sharedmemoryname", "shared memory name", typeof(string), "MYSQL", false));
  54. options.Add(new MySqlConnectionStringOption("useoldsyntax", "old syntax,oldsyntax,use old syntax", typeof(bool), false, true,
  55. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value)
  56. {
  57. MySqlTrace.LogWarning(-1, "Use Old Syntax is now obsolete. Please see documentation");
  58. msb.SetValue("useoldsyntax", value);
  59. },
  60. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender)
  61. {
  62. return (bool)msb.values["useoldsyntax"];
  63. }
  64. ));
  65. options.Add(new MySqlConnectionStringOption("connectiontimeout", "connection timeout,connect timeout", typeof(uint), (uint)15, false,
  66. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object Value)
  67. {
  68. uint value = (uint)Convert.ChangeType(Value, sender.BaseType);
  69. // Timeout in milliseconds should not exceed maximum for 32 bit
  70. // signed integer (~24 days). We truncate the value if it exceeds
  71. // maximum (MySqlCommand.CommandTimeout uses the same technique
  72. uint timeout = Math.Min(value, Int32.MaxValue / 1000);
  73. if (timeout != value)
  74. {
  75. MySqlTrace.LogWarning(-1, "Connection timeout value too large ("
  76. + value + " seconds). Changed to max. possible value" +
  77. +timeout + " seconds)");
  78. }
  79. msb.SetValue("connectiontimeout", timeout);
  80. },
  81. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender)
  82. {
  83. return (uint)msb.values["connectiontimeout"];
  84. }
  85. ));
  86. options.Add(new MySqlConnectionStringOption("defaultcommandtimeout", "command timeout,default command timeout", typeof(uint), ( uint )30, false));
  87. options.Add(new MySqlConnectionStringOption("usedefaultcommandtimeoutforef", "use default command timeout for ef", typeof(bool), false, false));
  88. // authentication options
  89. options.Add(new MySqlConnectionStringOption("user id", "uid,username,user name,user,userid", typeof(string), "", false));
  90. options.Add(new MySqlConnectionStringOption("password", "pwd", typeof(string), "", false));
  91. options.Add(new MySqlConnectionStringOption("persistsecurityinfo", "persist security info", typeof(bool), false, false));
  92. options.Add(new MySqlConnectionStringOption("encrypt", null, typeof(bool), false, true,
  93. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value)
  94. {
  95. // just for this case, reuse the logic to translate string to bool
  96. sender.ValidateValue(ref value);
  97. MySqlTrace.LogWarning(-1, "Encrypt is now obsolete. Use Ssl Mode instead");
  98. msb.SetValue("Ssl Mode", ( bool)value ? MySqlSslMode.Prefered : MySqlSslMode.None);
  99. },
  100. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender)
  101. {
  102. return msb.SslMode != MySqlSslMode.None;
  103. }
  104. ));
  105. options.Add(new MySqlConnectionStringOption("certificatefile", "certificate file", typeof(string), null, false));
  106. options.Add(new MySqlConnectionStringOption("certificatepassword", "certificate password", typeof(string), null, false));
  107. options.Add(new MySqlConnectionStringOption("certificatestorelocation", "certificate store location", typeof(MySqlCertificateStoreLocation), MySqlCertificateStoreLocation.None, false));
  108. options.Add(new MySqlConnectionStringOption("certificatethumbprint", "certificate thumb print", typeof(string), null, false));
  109. options.Add(new MySqlConnectionStringOption("integratedsecurity", "integrated security", typeof(bool), false, false,
  110. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value)
  111. {
  112. if (!Externals.MySql.Data.Common.Platform.IsWindows())
  113. throw new MySqlException("IntegratedSecurity is supported on Windows only");
  114. msb.SetValue("Integrated Security", value);
  115. },
  116. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender)
  117. {
  118. object val = msb.values["Integrated Security"];
  119. return (bool)val;
  120. }
  121. ));
  122. // Other properties
  123. options.Add(new MySqlConnectionStringOption("allowzerodatetime", "allow zero datetime", typeof(bool), false, false));
  124. options.Add(new MySqlConnectionStringOption("convertzerodatetime", "convert zero datetime", typeof(bool), false, false));
  125. options.Add(new MySqlConnectionStringOption("useusageadvisor", "use usage advisor,usage advisor", typeof(bool), false, false));
  126. options.Add(new MySqlConnectionStringOption("procedurecachesize", "procedure cache size,procedure cache,procedurecache", typeof(uint), ( uint )25, false));
  127. options.Add(new MySqlConnectionStringOption("useperformancemonitor", "use performance monitor,useperfmon,perfmon", typeof(bool), false, false));
  128. options.Add(new MySqlConnectionStringOption("ignoreprepare", "ignore prepare", typeof(bool), true, false));
  129. options.Add(new MySqlConnectionStringOption("useprocedurebodies", "use procedure bodies,procedure bodies", typeof(bool), true, true,
  130. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value)
  131. {
  132. sender.ValidateValue(ref value);
  133. MySqlTrace.LogWarning(-1, "Use Procedure Bodies is now obsolete. Use Check Parameters instead");
  134. msb.SetValue("checkparameters", value);
  135. msb.SetValue("useprocedurebodies", value);
  136. },
  137. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender)
  138. {
  139. return (bool)msb.values["useprocedurebodies"];
  140. }
  141. ));
  142. options.Add(new MySqlConnectionStringOption("autoenlist", "auto enlist", typeof(bool), true, false));
  143. options.Add(new MySqlConnectionStringOption("respectbinaryflags", "respect binary flags", typeof(bool), true, false));
  144. options.Add(new MySqlConnectionStringOption("treattinyasboolean", "treat tiny as boolean", typeof(bool), true, false));
  145. options.Add(new MySqlConnectionStringOption("allowuservariables", "allow user variables", typeof(bool), false, false));
  146. options.Add(new MySqlConnectionStringOption("interactivesession", "interactive session,interactive", typeof(bool), false, false));
  147. options.Add(new MySqlConnectionStringOption("functionsreturnstring", "functions return string", typeof(bool), false, false));
  148. options.Add(new MySqlConnectionStringOption("useaffectedrows", "use affected rows", typeof(bool), false, false));
  149. options.Add(new MySqlConnectionStringOption("oldguids", "old guids", typeof(bool), false, false));
  150. options.Add(new MySqlConnectionStringOption("keepalive", "keep alive", typeof(uint), (uint)0, false));
  151. options.Add(new MySqlConnectionStringOption("sqlservermode", "sql server mode", typeof(bool), false, false));
  152. options.Add(new MySqlConnectionStringOption("tablecaching", "table cache,tablecache", typeof(bool), false, false));
  153. options.Add(new MySqlConnectionStringOption("defaulttablecacheage", "default table cache age", typeof(int), ( int ) 60, false));
  154. options.Add(new MySqlConnectionStringOption("checkparameters", "check parameters", typeof(bool), true, false));
  155. options.Add(new MySqlConnectionStringOption("replication", null, typeof(bool), false, false));
  156. options.Add(new MySqlConnectionStringOption("exceptioninterceptors", "exception interceptors", typeof(string), null, false));
  157. options.Add(new MySqlConnectionStringOption("commandinterceptors", "command interceptors", typeof(string), null, false));
  158. options.Add(new MySqlConnectionStringOption("includesecurityasserts", "include security asserts", typeof(bool), false, false));
  159. // pooling options
  160. options.Add(new MySqlConnectionStringOption("connectionlifetime", "connection lifetime", typeof(uint), ( uint )0, false));
  161. options.Add(new MySqlConnectionStringOption("pooling", null, typeof(bool), true, false));
  162. options.Add(new MySqlConnectionStringOption("minpoolsize", "minimumpoolsize,min pool size,minimum pool size", typeof(uint), (uint)0, false));
  163. options.Add(new MySqlConnectionStringOption("maxpoolsize", "maximumpoolsize,max pool size,maximum pool size", typeof(uint), (uint)100, false));
  164. options.Add(new MySqlConnectionStringOption("connectionreset", "connection reset", typeof(bool), false, false));
  165. options.Add(new MySqlConnectionStringOption("cacheserverproperties", "cache server properties", typeof(bool), false, false));
  166. // language and charset options
  167. options.Add(new MySqlConnectionStringOption("characterset", "character set,charset", typeof(string), "", false));
  168. options.Add(new MySqlConnectionStringOption("treatblobsasutf8", "treat blobs as utf8", typeof(bool), false, false));
  169. options.Add(new MySqlConnectionStringOption("blobasutf8includepattern", null, typeof(string), "", false));
  170. options.Add(new MySqlConnectionStringOption("blobasutf8excludepattern", null, typeof(string), "", false));
  171. options.Add(new MySqlConnectionStringOption("sslmode", "ssl mode", typeof(MySqlSslMode), MySqlSslMode.Preferred, false));
  172. }
  173. public MySqlConnectionStringBuilder()
  174. {
  175. HasProcAccess = true;
  176. // Populate initial values
  177. lock (this)
  178. {
  179. for (int i = 0; i < options.Options.Count; i++)
  180. {
  181. values[options.Options[i].Keyword] = options.Options[i].DefaultValue;
  182. }
  183. }
  184. }
  185. public MySqlConnectionStringBuilder(string connStr)
  186. : this()
  187. {
  188. lock (this)
  189. {
  190. ConnectionString = connStr;
  191. }
  192. }
  193. #region Server Properties
  194. /// <summary>
  195. /// Gets or sets the name of the server.
  196. /// </summary>
  197. /// <value>The server.</value>
  198. [Category("Connection")]
  199. [Description("Server to connect to")]
  200. [RefreshProperties(RefreshProperties.All)]
  201. public string Server
  202. {
  203. get { return this["server"] as string; }
  204. set { this[ "server" ] = value; }
  205. }
  206. /// <summary>
  207. /// Gets or sets the name of the database the connection should
  208. /// initially connect to.
  209. /// </summary>
  210. [Category("Connection")]
  211. [Description("Database to use initially")]
  212. [RefreshProperties(RefreshProperties.All)]
  213. public string Database
  214. {
  215. get { return values["database"] as string; }
  216. set { SetValue("database", value); }
  217. }
  218. /// <summary>
  219. /// Gets or sets the protocol that should be used for communicating
  220. /// with MySQL.
  221. /// </summary>
  222. [Category("Connection")]
  223. [DisplayName("Connection Protocol")]
  224. [Description("Protocol to use for connection to MySQL")]
  225. [RefreshProperties(RefreshProperties.All)]
  226. public MySqlConnectionProtocol ConnectionProtocol
  227. {
  228. get { return (MySqlConnectionProtocol)values["protocol"]; }
  229. set { SetValue("protocol", value); }
  230. }
  231. /// <summary>
  232. /// Gets or sets the name of the named pipe that should be used
  233. /// for communicating with MySQL.
  234. /// </summary>
  235. [Category("Connection")]
  236. [DisplayName("Pipe Name")]
  237. [Description("Name of pipe to use when connecting with named pipes (Win32 only)")]
  238. [RefreshProperties(RefreshProperties.All)]
  239. public string PipeName
  240. {
  241. get { return (string)values["pipe"]; }
  242. set { SetValue("pipe", value); }
  243. }
  244. /// <summary>
  245. /// Gets or sets a boolean value that indicates whether this connection
  246. /// should use compression.
  247. /// </summary>
  248. [Category("Connection")]
  249. [DisplayName("Use Compression")]
  250. [Description("Should the connection use compression")]
  251. [RefreshProperties(RefreshProperties.All)]
  252. public bool UseCompression
  253. {
  254. get { return (bool)values["compress"]; }
  255. set { SetValue("compress", value); }
  256. }
  257. /// <summary>
  258. /// Gets or sets a boolean value that indicates whether this connection will allow
  259. /// commands to send multiple SQL statements in one execution.
  260. /// </summary>
  261. [Category("Connection")]
  262. [DisplayName("Allow Batch")]
  263. [Description("Allows execution of multiple SQL commands in a single statement")]
  264. [RefreshProperties(RefreshProperties.All)]
  265. public bool AllowBatch
  266. {
  267. get { return (bool)values["allowbatch"]; }
  268. set { SetValue("allowbatch", value); }
  269. }
  270. /// <summary>
  271. /// Gets or sets a boolean value that indicates whether logging is enabled.
  272. /// </summary>
  273. [Category("Connection")]
  274. [Description("Enables output of diagnostic messages")]
  275. [RefreshProperties(RefreshProperties.All)]
  276. public bool Logging
  277. {
  278. get { return (bool)values["logging"]; }
  279. set { SetValue("logging", value); }
  280. }
  281. /// <summary>
  282. /// Gets or sets the base name of the shared memory objects used to
  283. /// communicate with MySQL when the shared memory protocol is being used.
  284. /// </summary>
  285. [Category("Connection")]
  286. [DisplayName("Shared Memory Name")]
  287. [Description("Name of the shared memory object to use")]
  288. [RefreshProperties(RefreshProperties.All)]
  289. public string SharedMemoryName
  290. {
  291. get { return (string)values["sharedmemoryname"]; }
  292. set { SetValue("sharedmemoryname", value); }
  293. }
  294. /// <summary>
  295. /// Gets or sets a boolean value that indicates whether this connection uses
  296. /// the old style (@) parameter markers or the new (?) style.
  297. /// </summary>
  298. [Category("Connection")]
  299. [DisplayName("Use Old Syntax")]
  300. [Description("Allows the use of old style @ syntax for parameters")]
  301. [RefreshProperties(RefreshProperties.All)]
  302. // [Obsolete("Use Old Syntax is no longer needed. See documentation")]
  303. public bool UseOldSyntax
  304. {
  305. get { return (bool)values["useoldsyntax"]; }
  306. set { SetValue("useoldsyntax", value); }
  307. }
  308. /// <summary>
  309. /// Gets or sets the port number that is used when the socket
  310. /// protocol is being used.
  311. /// </summary>
  312. [Category("Connection")]
  313. [Description("Port to use for TCP/IP connections")]
  314. [RefreshProperties(RefreshProperties.All)]
  315. public uint Port
  316. {
  317. get { return (uint)values["port"]; }
  318. set { SetValue("port", value); }
  319. }
  320. /// <summary>
  321. /// Gets or sets the connection timeout.
  322. /// </summary>
  323. [Category("Connection")]
  324. [DisplayName("Connect Timeout")]
  325. [Description("The length of time (in seconds) to wait for a connection " +
  326. "to the server before terminating the attempt and generating an error.")]
  327. [RefreshProperties(RefreshProperties.All)]
  328. public uint ConnectionTimeout
  329. {
  330. get { return (uint)values["connectiontimeout"]; }
  331. set
  332. {
  333. // Timeout in milliseconds should not exceed maximum for 32 bit
  334. // signed integer (~24 days). We truncate the value if it exceeds
  335. // maximum (MySqlCommand.CommandTimeout uses the same technique
  336. uint timeout = Math.Min(value, Int32.MaxValue / 1000);
  337. if (timeout != value)
  338. {
  339. MySqlTrace.LogWarning(-1, "Connection timeout value too large ("
  340. + value + " seconds). Changed to max. possible value" +
  341. +timeout + " seconds)");
  342. }
  343. SetValue("connectiontimeout", timeout);
  344. }
  345. }
  346. /// <summary>
  347. /// Gets or sets the default command timeout.
  348. /// </summary>
  349. [Category("Connection")]
  350. [DisplayName("Default Command Timeout")]
  351. [Description(@"The default timeout that MySqlCommand objects will use
  352. unless changed.")]
  353. [RefreshProperties(RefreshProperties.All)]
  354. public uint DefaultCommandTimeout
  355. {
  356. get { return (uint)values["defaultcommandtimeout"]; }
  357. set { SetValue("defaultcommandtimeout", value); }
  358. }
  359. #endregion
  360. #region Authentication Properties
  361. /// <summary>
  362. /// Gets or sets the user id that should be used to connect with.
  363. /// </summary>
  364. [Category("Security")]
  365. [DisplayName("User Id")]
  366. [Description("Indicates the user ID to be used when connecting to the data source.")]
  367. [RefreshProperties(RefreshProperties.All)]
  368. public string UserID
  369. {
  370. get { return (string)values["user id"]; }
  371. set { SetValue("user id", value); }
  372. }
  373. /// <summary>
  374. /// Gets or sets the password that should be used to connect with.
  375. /// </summary>
  376. [Category("Security")]
  377. [Description("Indicates the password to be used when connecting to the data source.")]
  378. [PasswordPropertyText(true)]
  379. [RefreshProperties(RefreshProperties.All)]
  380. public string Password
  381. {
  382. get { return (string)values["password"]; }
  383. set { SetValue("password", value); }
  384. }
  385. /// <summary>
  386. /// Gets or sets a boolean value that indicates if the password should be persisted
  387. /// in the connection string.
  388. /// </summary>
  389. [Category("Security")]
  390. [DisplayName("Persist Security Info")]
  391. [Description("When false, security-sensitive information, such as the password, " +
  392. "is not returned as part of the connection if the connection is open or " +
  393. "has ever been in an open state.")]
  394. [RefreshProperties(RefreshProperties.All)]
  395. public bool PersistSecurityInfo
  396. {
  397. get { return (bool)values["persistsecurityinfo"]; }
  398. set { SetValue("persistsecurityinfo", value); }
  399. }
  400. [Category("Authentication")]
  401. [Description("Should the connection use SSL.")]
  402. [Obsolete("Use Ssl Mode instead.")]
  403. internal bool Encrypt
  404. {
  405. get { return SslMode != MySqlSslMode.None; }
  406. set
  407. {
  408. SetValue("Ssl Mode", value ? MySqlSslMode.Prefered : MySqlSslMode.None);
  409. }
  410. }
  411. [Category("Authentication")]
  412. [DisplayName("Certificate File")]
  413. [Description("Certificate file in PKCS#12 format (.pfx)")]
  414. public string CertificateFile
  415. {
  416. get { return (string)values["certificatefile"]; }
  417. set { SetValue("certificatefile", value); }
  418. }
  419. [Category("Authentication")]
  420. [DisplayName("Certificate Password")]
  421. [Description("Password for certificate file")]
  422. public string CertificatePassword
  423. {
  424. get { return (string)values["certificatepassword"]; }
  425. set { SetValue("certificatepassword", value); }
  426. }
  427. [Category("Authentication")]
  428. [DisplayName("Certificate Store Location")]
  429. [Description("Certificate Store Location for client certificates")]
  430. [DefaultValue(MySqlCertificateStoreLocation.None)]
  431. public MySqlCertificateStoreLocation CertificateStoreLocation
  432. {
  433. get { return (MySqlCertificateStoreLocation)values["certificatestorelocation"]; }
  434. set { SetValue("certificatestorelocation", value); }
  435. }
  436. [Category("Authentication")]
  437. [DisplayName("Certificate Thumbprint")]
  438. [Description("Certificate thumbprint. Can be used together with Certificate " +
  439. "Store Location parameter to uniquely identify certificate to be used " +
  440. "for SSL authentication.")]
  441. public string CertificateThumbprint
  442. {
  443. get { return (string)values["certificatethumbprint"]; }
  444. set { SetValue("certificatethumbprint", value); }
  445. }
  446. [Category("Authentication")]
  447. [DisplayName("Integrated Security")]
  448. [Description("Use windows authentication when connecting to server")]
  449. [DefaultValue(false)]
  450. public bool IntegratedSecurity
  451. {
  452. get { return (bool)values["integratedsecurity"]; }
  453. set
  454. {
  455. if (!Externals.MySql.Data.Common.Platform.IsWindows())
  456. throw new MySqlException("IntegratedSecurity is supported on Windows only");
  457. SetValue("integratedsecurity", value);
  458. }
  459. }
  460. #endregion
  461. #region Other Properties
  462. /// <summary>
  463. /// Gets or sets a boolean value that indicates if zero date time values are supported.
  464. /// </summary>
  465. [Category("Advanced")]
  466. [DisplayName("Allow Zero Datetime")]
  467. [Description("Should zero datetimes be supported")]
  468. [DefaultValue(false)]
  469. [RefreshProperties(RefreshProperties.All)]
  470. public bool AllowZeroDateTime
  471. {
  472. get { return (bool)values["allowzerodatetime"]; }
  473. set { SetValue("allowzerodatetime", value); }
  474. }
  475. /// <summary>
  476. /// Gets or sets a boolean value indicating if zero datetime values should be
  477. /// converted to DateTime.MinValue.
  478. /// </summary>
  479. [Category("Advanced")]
  480. [DisplayName("Convert Zero Datetime")]
  481. [Description("Should illegal datetime values be converted to DateTime.MinValue")]
  482. [DefaultValue(false)]
  483. [RefreshProperties(RefreshProperties.All)]
  484. public bool ConvertZeroDateTime
  485. {
  486. get { return (bool)values["convertzerodatetime"]; }
  487. set { SetValue("convertzerodatetime", value); }
  488. }
  489. /// <summary>
  490. /// Gets or sets a boolean value indicating if the Usage Advisor should be enabled.
  491. /// </summary>
  492. [Category("Advanced")]
  493. [DisplayName("Use Usage Advisor")]
  494. [Description("Logs inefficient database operations")]
  495. [DefaultValue(false)]
  496. [RefreshProperties(RefreshProperties.All)]
  497. public bool UseUsageAdvisor
  498. {
  499. get { return (bool)values["useusageadvisor"]; }
  500. set { SetValue("useusageadvisor", value); }
  501. }
  502. /// <summary>
  503. /// Gets or sets the size of the stored procedure cache.
  504. /// </summary>
  505. [Category("Advanced")]
  506. [DisplayName("Procedure Cache Size")]
  507. [Description("Indicates how many stored procedures can be cached at one time. " +
  508. "A value of 0 effectively disables the procedure cache.")]
  509. [DefaultValue(25)]
  510. [RefreshProperties(RefreshProperties.All)]
  511. public uint ProcedureCacheSize
  512. {
  513. get { return (uint)values["procedurecachesize"]; }
  514. set { SetValue("procedurecachesize", value); }
  515. }
  516. /// <summary>
  517. /// Gets or sets a boolean value indicating if the permon hooks should be enabled.
  518. /// </summary>
  519. [Category("Advanced")]
  520. [DisplayName("Use Performance Monitor")]
  521. [Description("Indicates that performance counters should be updated during execution.")]
  522. [DefaultValue(false)]
  523. [RefreshProperties(RefreshProperties.All)]
  524. public bool UsePerformanceMonitor
  525. {
  526. get { return (bool)values["useperformancemonitor"]; }
  527. set { SetValue("useperformancemonitor", value); }
  528. }
  529. /// <summary>
  530. /// Gets or sets a boolean value indicating if calls to Prepare() should be ignored.
  531. /// </summary>
  532. [Category("Advanced")]
  533. [DisplayName("Ignore Prepare")]
  534. [Description("Instructs the provider to ignore any attempts to prepare a command.")]
  535. [DefaultValue(true)]
  536. [RefreshProperties(RefreshProperties.All)]
  537. public bool IgnorePrepare
  538. {
  539. get { return (bool)values["ignoreprepare"]; }
  540. set { SetValue("ignoreprepare", value); }
  541. }
  542. [Category("Advanced")]
  543. [DisplayName("Use Procedure Bodies")]
  544. [Description("Indicates if stored procedure bodies will be available for parameter detection.")]
  545. [DefaultValue(true)]
  546. [Obsolete("Use CheckParameters instead")]
  547. public bool UseProcedureBodies
  548. {
  549. get { return (bool)values["useprocedurebodies"]; }
  550. set { SetValue("useprocedurebodies", value); }
  551. }
  552. [Category("Advanced")]
  553. [DisplayName("Auto Enlist")]
  554. [Description("Should the connetion automatically enlist in the active connection, if there are any.")]
  555. [DefaultValue(true)]
  556. [RefreshProperties(RefreshProperties.All)]
  557. public bool AutoEnlist
  558. {
  559. get { return (bool)values["autoenlist"]; }
  560. set { SetValue("autoenlist", value); }
  561. }
  562. [Category("Advanced")]
  563. [DisplayName("Respect Binary Flags")]
  564. [Description("Should binary flags on column metadata be respected.")]
  565. [DefaultValue(true)]
  566. [RefreshProperties(RefreshProperties.All)]
  567. public bool RespectBinaryFlags
  568. {
  569. get { return (bool)values["respectbinaryflags"]; }
  570. set { SetValue("respectbinaryflags", value); }
  571. }
  572. [Category("Advanced")]
  573. [DisplayName("Treat Tiny As Boolean")]
  574. [Description("Should the provider treat TINYINT(1) columns as boolean.")]
  575. [DefaultValue(true)]
  576. [RefreshProperties(RefreshProperties.All)]
  577. public bool TreatTinyAsBoolean
  578. {
  579. get { return (bool)values["treattinyasboolean"]; }
  580. set { SetValue("treattinyasboolean", value); }
  581. }
  582. [Category("Advanced")]
  583. [DisplayName("Allow User Variables")]
  584. [Description("Should the provider expect user variables to appear in the SQL.")]
  585. [DefaultValue(false)]
  586. [RefreshProperties(RefreshProperties.All)]
  587. public bool AllowUserVariables
  588. {
  589. get { return (bool)values["allowuservariables"]; }
  590. set { SetValue("allowuservariables", value); }
  591. }
  592. [Category("Advanced")]
  593. [DisplayName("Interactive Session")]
  594. [Description("Should this session be considered interactive?")]
  595. [DefaultValue(false)]
  596. [RefreshProperties(RefreshProperties.All)]
  597. public bool InteractiveSession
  598. {
  599. get { return (bool)values["interactivesession"]; }
  600. set { SetValue("interactivesession", value); }
  601. }
  602. [Category("Advanced")]
  603. [DisplayName("Functions Return String")]
  604. [Description("Should all server functions be treated as returning string?")]
  605. [DefaultValue(false)]
  606. public bool FunctionsReturnString
  607. {
  608. get { return (bool)values["functionsreturnstring"]; }
  609. set { SetValue("functionsreturnstring", value); }
  610. }
  611. [Category("Advanced")]
  612. [DisplayName("Use Affected Rows")]
  613. [Description("Should the returned affected row count reflect affected rows instead of found rows?")]
  614. [DefaultValue(false)]
  615. public bool UseAffectedRows
  616. {
  617. get { return (bool)values["useaffectedrows"]; }
  618. set { SetValue("useaffectedrows", value); }
  619. }
  620. [Category("Advanced")]
  621. [DisplayName("Old Guids")]
  622. [Description("Treat binary(16) columns as guids")]
  623. [DefaultValue(false)]
  624. public bool OldGuids
  625. {
  626. get { return (bool)values["oldguids"]; }
  627. set { SetValue("oldguids", value); }
  628. }
  629. [DisplayName("Keep Alive")]
  630. [Description("For TCP connections, idle connection time measured in seconds, before the first keepalive packet is sent." +
  631. "A value of 0 indicates that keepalive is not used.")]
  632. [DefaultValue(0)]
  633. public uint Keepalive
  634. {
  635. get { return (uint)values["keepalive"]; }
  636. set { SetValue("keepalive", value); }
  637. }
  638. [Category("Advanced")]
  639. [DisplayName("Sql Server Mode")]
  640. [Description("Allow Sql Server syntax. " +
  641. "A value of yes allows symbols to be enclosed with [] instead of ``. This does incur " +
  642. "a performance hit so only use when necessary.")]
  643. [DefaultValue(false)]
  644. public bool SqlServerMode
  645. {
  646. get { return (bool)values["sqlservermode"]; }
  647. set { SetValue("sqlservermode", value); }
  648. }
  649. [Category("Advanced")]
  650. [DisplayName("Table Cache")]
  651. [Description(@"Enables or disables caching of TableDirect command.
  652. A value of yes enables the cache while no disables it.")]
  653. [DefaultValue(false)]
  654. public bool TableCaching
  655. {
  656. get { return (bool)values["tablecaching"]; }
  657. set { SetValue("tablecachig", value); }
  658. }
  659. [Category("Advanced")]
  660. [DisplayName("Default Table Cache Age")]
  661. [Description(@"Specifies how long a TableDirect result should be cached in seconds.")]
  662. [DefaultValue(60)]
  663. public int DefaultTableCacheAge
  664. {
  665. get { return (int)values["defaulttablecacheage"]; }
  666. set { SetValue("defaulttablecacheage", value); }
  667. }
  668. [Category("Advanced")]
  669. [DisplayName("Check Parameters")]
  670. [Description("Indicates if stored routine parameters should be checked against the server.")]
  671. [DefaultValue(true)]
  672. public bool CheckParameters
  673. {
  674. get { return (bool)values["checkparameters"]; }
  675. set { SetValue("checkparameters", value); }
  676. }
  677. [Category("Advanced")]
  678. [DisplayName("Replication")]
  679. [Description("Indicates if this connection is to use replicated servers.")]
  680. [DefaultValue(false)]
  681. public bool Replication
  682. {
  683. get { return (bool)values["replication"]; }
  684. set { SetValue("replication", value); }
  685. }
  686. [Category("Advanced")]
  687. [DisplayName("Exception Interceptors")]
  688. [Description("The list of interceptors that can triage thrown MySqlExceptions.")]
  689. public string ExceptionInterceptors
  690. {
  691. get { return (string)values["exceptioninterceptors"]; }
  692. set { SetValue("exceptioninterceptors", value); }
  693. }
  694. [Category("Advanced")]
  695. [DisplayName("Command Interceptors")]
  696. [Description("The list of interceptors that can intercept command operations.")]
  697. public string CommandInterceptors
  698. {
  699. get { return (string)values["commandinterceptors"]; }
  700. set { SetValue("commandinterceptors", value); }
  701. }
  702. [Category("Advanced")]
  703. [DisplayName("Include Security Asserts")]
  704. [Description("Include security asserts to support Medium Trust")]
  705. [DefaultValue(false)]
  706. public bool IncludeSecurityAsserts
  707. {
  708. get { return (bool)values["includesecurityasserts"]; }
  709. set { SetValue("includesecurityasserts", value); }
  710. }
  711. #endregion
  712. #region Pooling Properties
  713. /// <summary>
  714. /// Gets or sets the lifetime of a pooled connection.
  715. /// </summary>
  716. [Category("Pooling")]
  717. [DisplayName("Connection Lifetime")]
  718. [Description("The minimum amount of time (in seconds) for this connection to " +
  719. "live in the pool before being destroyed.")]
  720. [DefaultValue(0)]
  721. [RefreshProperties(RefreshProperties.All)]
  722. public uint ConnectionLifeTime
  723. {
  724. get { return (uint)values["connectionlifetime"]; }
  725. set { SetValue("connectionlifetime", value); }
  726. }
  727. /// <summary>
  728. /// Gets or sets a boolean value indicating if connection pooling is enabled.
  729. /// </summary>
  730. [Category("Pooling")]
  731. [Description("When true, the connection object is drawn from the appropriate " +
  732. "pool, or if necessary, is created and added to the appropriate pool.")]
  733. [DefaultValue(true)]
  734. [RefreshProperties(RefreshProperties.All)]
  735. public bool Pooling
  736. {
  737. get { return (bool)values["pooling"]; }
  738. set { SetValue("pooling", value); }
  739. }
  740. /// <summary>
  741. /// Gets the minimum connection pool size.
  742. /// </summary>
  743. [Category("Pooling")]
  744. [DisplayName("Minimum Pool Size")]
  745. [Description("The minimum number of connections allowed in the pool.")]
  746. [DefaultValue(0)]
  747. [RefreshProperties(RefreshProperties.All)]
  748. public uint MinimumPoolSize
  749. {
  750. get { return (uint)values["minpoolsize"]; }
  751. set { SetValue("minpoolsize", value); }
  752. }
  753. /// <summary>
  754. /// Gets or sets the maximum connection pool setting.
  755. /// </summary>
  756. [Category("Pooling")]
  757. [DisplayName("Maximum Pool Size")]
  758. [Description("The maximum number of connections allowed in the pool.")]
  759. [DefaultValue(100)]
  760. [RefreshProperties(RefreshProperties.All)]
  761. public uint MaximumPoolSize
  762. {
  763. get { return (uint)values["maxpoolsize"]; }
  764. set { SetValue("maxpoolsize", value); }
  765. }
  766. /// <summary>
  767. /// Gets or sets a boolean value indicating if the connection should be reset when retrieved
  768. /// from the pool.
  769. /// </summary>
  770. [Category("Pooling")]
  771. [DisplayName("Connection Reset")]
  772. [Description("When true, indicates the connection state is reset when removed from the pool.")]
  773. [DefaultValue(false)]
  774. [RefreshProperties(RefreshProperties.All)]
  775. public bool ConnectionReset
  776. {
  777. get { return (bool)values["connectionreset"]; }
  778. set { SetValue("connectionreset", value); }
  779. }
  780. [Category("Pooling")]
  781. [DisplayName("Cache Server Properties")]
  782. [Description("When true, server properties will be cached after the first server in the pool is created")]
  783. [DefaultValue(false)]
  784. [RefreshProperties(RefreshProperties.All)]
  785. public bool CacheServerProperties
  786. {
  787. get { return (bool)values["cacheserverproperties"]; }
  788. set { SetValue("cacheserverproperties", value); }
  789. }
  790. #endregion
  791. #region Language and Character Set Properties
  792. /// <summary>
  793. /// Gets or sets the character set that should be used for sending queries to the server.
  794. /// </summary>
  795. [DisplayName("Character Set")]
  796. [Category("Advanced")]
  797. [Description("Character set this connection should use")]
  798. [DefaultValue("")]
  799. [RefreshProperties(RefreshProperties.All)]
  800. public string CharacterSet
  801. {
  802. get { return (string)values["characterset"]; }
  803. set { SetValue("characterset", value); }
  804. }
  805. /// <summary>
  806. /// Indicates whether the driver should treat binary blobs as UTF8
  807. /// </summary>
  808. [DisplayName("Treat Blobs As UTF8")]
  809. [Category("Advanced")]
  810. [Description("Should binary blobs be treated as UTF8")]
  811. [DefaultValue(false)]
  812. [RefreshProperties(RefreshProperties.All)]
  813. public bool TreatBlobsAsUTF8
  814. {
  815. get { return (bool)values["treatblobsasutf8"]; }
  816. set { SetValue("treatblobsasutf8", value); }
  817. }
  818. /// <summary>
  819. /// Gets or sets the pattern that matches the columns that should be treated as UTF8
  820. /// </summary>
  821. [Category("Advanced")]
  822. [Description("Pattern that matches columns that should be treated as UTF8")]
  823. [RefreshProperties(RefreshProperties.All)]
  824. public string BlobAsUTF8IncludePattern
  825. {
  826. get { return (string)values["blobasutf8includepattern"]; }
  827. set { SetValue("blobasutf8includepattern", value); }
  828. }
  829. /// <summary>
  830. /// Gets or sets the pattern that matches the columns that should not be treated as UTF8
  831. /// </summary>
  832. [Category("Advanced")]
  833. [Description("Pattern that matches columns that should not be treated as UTF8")]
  834. [RefreshProperties(RefreshProperties.All)]
  835. public string BlobAsUTF8ExcludePattern
  836. {
  837. get { return (string)values["blobasutf8excludepattern"]; }
  838. set { SetValue("blobasutf8excludepattern", value); }
  839. }
  840. /// <summary>
  841. /// Indicates whether to use SSL connections and how to handle server certificate errors.
  842. /// </summary>
  843. [DisplayName("Ssl Mode")]
  844. [Category("Security")]
  845. [Description("SSL properties for connection")]
  846. [DefaultValue(MySqlSslMode.None)]
  847. public MySqlSslMode SslMode
  848. {
  849. get { return (MySqlSslMode)values["sslmode"]; }
  850. set { SetValue("sslmode", value); }
  851. }
  852. #endregion
  853. #region Backwards compatibility properties
  854. [DisplayName("Use Default Command Timeout For EF")]
  855. [Category("Backwards Compatibility")]
  856. [Description("Enforces the command timeout of EFMySqlCommand to the value provided in 'DefaultCommandTimeout' property")]
  857. [DefaultValue(false)]
  858. public bool UseDefaultCommandTimeoutForEF
  859. {
  860. get { return (bool)values["usedefaultcommandtimeoutforef"]; }
  861. set { SetValue("usedefaultcommandtimeoutforef", value); }
  862. }
  863. #endregion
  864. #region Fabric Properties
  865. public string FabricGroup { get; internal set; }
  866. public string ShardingTable { get; internal set; }
  867. public object ShardingKey { get; internal set; }
  868. public int? FabricServerMode { get; internal set; }
  869. public int? FabricScope { get; internal set; }
  870. #endregion
  871. internal bool HasProcAccess { get; set; }
  872. public override object this[string keyword]
  873. {
  874. get { MySqlConnectionStringOption opt = GetOption(keyword); return opt.Getter( this, opt ); }
  875. set { MySqlConnectionStringOption opt = GetOption(keyword); opt.Setter( this, opt, value); }
  876. }
  877. internal Regex GetBlobAsUTF8IncludeRegex()
  878. {
  879. if (String.IsNullOrEmpty(BlobAsUTF8IncludePattern)) return null;
  880. return new Regex(BlobAsUTF8IncludePattern);
  881. }
  882. internal Regex GetBlobAsUTF8ExcludeRegex()
  883. {
  884. if (String.IsNullOrEmpty(BlobAsUTF8ExcludePattern)) return null;
  885. return new Regex(BlobAsUTF8ExcludePattern);
  886. }
  887. public override void Clear()
  888. {
  889. base.Clear();
  890. lock (this)
  891. {
  892. foreach (var option in options.Options)
  893. if (option.DefaultValue != null)
  894. values[option.Keyword] = option.DefaultValue;
  895. else
  896. values[option.Keyword] = null;
  897. }
  898. }
  899. internal void SetValue(string keyword, object value)
  900. {
  901. MySqlConnectionStringOption option = GetOption(keyword);
  902. option.ValidateValue(ref value);
  903. // remove all related keywords
  904. option.Clean(this);
  905. if (value != null)
  906. {
  907. lock (this)
  908. {
  909. // set value for the given keyword
  910. values[option.Keyword] = value;
  911. base[keyword] = value;
  912. }
  913. }
  914. }
  915. private MySqlConnectionStringOption GetOption(string key)
  916. {
  917. MySqlConnectionStringOption option = options.Get(key);
  918. if (option == null)
  919. throw new ArgumentException(Resources.KeywordNotSupported, key);
  920. else
  921. return option;
  922. }
  923. public override bool ContainsKey(string keyword)
  924. {
  925. MySqlConnectionStringOption option = options.Get(keyword);
  926. return option != null;
  927. }
  928. public override bool Remove(string keyword)
  929. {
  930. bool removed = false;
  931. lock (this) { removed = base.Remove(keyword); }
  932. if (!removed) return false;
  933. MySqlConnectionStringOption option = GetOption(keyword);
  934. lock (this)
  935. {
  936. values[option.Keyword] = option.DefaultValue;
  937. }
  938. return true;
  939. }
  940. public string GetConnectionString(bool includePass)
  941. {
  942. if (includePass) return ConnectionString;
  943. StringBuilder conn = new StringBuilder();
  944. string delimiter = "";
  945. foreach (string key in this.Keys)
  946. {
  947. if (String.Compare(key, "password", StringComparison.OrdinalIgnoreCase) == 0 ||
  948. String.Compare(key, "pwd", StringComparison.OrdinalIgnoreCase) == 0) continue;
  949. conn.AppendFormat(CultureInfo.CurrentCulture, "{0}{1}={2}",
  950. delimiter, key, this[key]);
  951. delimiter = ";";
  952. }
  953. return conn.ToString();
  954. }
  955. public override bool Equals(object obj)
  956. {
  957. MySqlConnectionStringBuilder other = obj as MySqlConnectionStringBuilder;
  958. if( obj == null )
  959. return false;
  960. if( this.values.Count != other.values.Count ) return false;
  961. foreach (KeyValuePair<string, object> kvp in this.values)
  962. {
  963. if (other.values.ContainsKey(kvp.Key))
  964. {
  965. object v = other.values[kvp.Key];
  966. if (v == null && kvp.Value != null) return false;
  967. if (kvp.Value == null && v != null) return false;
  968. if (kvp.Value == null && v == null) return true;
  969. if (!v.Equals(kvp.Value)) return false;
  970. }
  971. else
  972. {
  973. return false;
  974. }
  975. }
  976. return true;
  977. }
  978. }
  979. class MySqlConnectionStringOption
  980. {
  981. public MySqlConnectionStringOption(string keyword, string synonyms, Type baseType, object defaultValue, bool obsolete,
  982. SetterDelegate setter, GetterDelegate getter )
  983. {
  984. Keyword = StringUtility.ToLowerInvariant(keyword);
  985. if (synonyms != null)
  986. Synonyms = StringUtility.ToLowerInvariant( synonyms ).Split(',');
  987. BaseType = baseType;
  988. Obsolete = obsolete;
  989. DefaultValue = defaultValue;
  990. Setter = setter;
  991. Getter = getter;
  992. }
  993. public MySqlConnectionStringOption(string keyword, string synonyms, Type baseType, object defaultValue, bool obsolete) :
  994. this(keyword, synonyms, baseType, defaultValue, obsolete,
  995. delegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value)
  996. {
  997. sender.ValidateValue(ref value);
  998. //if ( sender.BaseType.IsEnum )
  999. // msb.SetValue( sender.Keyword, Enum.Parse( sender.BaseType, ( string )value, true ));
  1000. //else
  1001. msb.SetValue(sender.Keyword, Convert.ChangeType(value, sender.BaseType));
  1002. },
  1003. delegate (MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender)
  1004. {
  1005. return msb.values[ sender.Keyword ];
  1006. }
  1007. )
  1008. {
  1009. }
  1010. public string[] Synonyms { get; private set; }
  1011. public bool Obsolete { get; private set; }
  1012. public Type BaseType { get; private set; }
  1013. public string Keyword { get; private set; }
  1014. public object DefaultValue { get; private set; }
  1015. public SetterDelegate Setter { get; private set; }
  1016. public GetterDelegate Getter { get; private set; }
  1017. internal delegate void SetterDelegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value);
  1018. internal delegate object GetterDelegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender);
  1019. public bool HasKeyword(string key)
  1020. {
  1021. if (Keyword == key) return true;
  1022. if (Synonyms == null) return false;
  1023. foreach (var syn in Synonyms)
  1024. if (syn == key) return true;
  1025. return false;
  1026. }
  1027. public void Clean(MySqlConnectionStringBuilder builder)
  1028. {
  1029. builder.Remove(Keyword);
  1030. if (Synonyms == null) return;
  1031. foreach (var syn in Synonyms)
  1032. builder.Remove(syn);
  1033. }
  1034. public void ValidateValue(ref object value)
  1035. {
  1036. bool b;
  1037. if (value == null) return;
  1038. string typeName = BaseType.Name;
  1039. Type valueType = value.GetType();
  1040. if (valueType.Name == "String" ) {
  1041. if( BaseType == valueType) return;
  1042. else if (BaseType == typeof(bool))
  1043. {
  1044. if (string.Compare("yes", ( string )value, StringComparison.OrdinalIgnoreCase) == 0) value = true;
  1045. else if (string.Compare("no", (string)value, StringComparison.OrdinalIgnoreCase) == 0) value = false;
  1046. else if (Boolean.TryParse(value.ToString(), out b)) value = b;
  1047. else throw new ArgumentException(String.Format(Resources.ValueNotCorrectType, value));
  1048. return;
  1049. }
  1050. }
  1051. if (typeName == "Boolean" && Boolean.TryParse(value.ToString(), out b)) { value = b; return; }
  1052. UInt64 uintVal;
  1053. if (typeName.StartsWith("UInt64") && UInt64.TryParse(value.ToString(), out uintVal)) { value = uintVal; return; }
  1054. UInt32 uintVal32;
  1055. if (typeName.StartsWith("UInt32") && UInt32.TryParse(value.ToString(), out uintVal32)) { value = uintVal32; return; }
  1056. Int64 intVal;
  1057. if (typeName.StartsWith("Int64") && Int64.TryParse(value.ToString(), out intVal)) { value = intVal; return; }
  1058. Int32 intVal32;
  1059. if (typeName.StartsWith("Int32") && Int32.TryParse(value.ToString(), out intVal32)) { value = intVal32; return; }
  1060. object objValue;
  1061. Type baseType = BaseType.BaseType;
  1062. if (baseType != null && baseType.Name == "Enum" && ParseEnum(value.ToString(), out objValue))
  1063. {
  1064. value = objValue; return;
  1065. }
  1066. throw new ArgumentException(String.Format(Resources.ValueNotCorrectType, value));
  1067. }
  1068. private bool ParseEnum(string requestedValue, out object value)
  1069. {
  1070. value = null;
  1071. try
  1072. {
  1073. value = Enum.Parse(BaseType, requestedValue, true);
  1074. return true;
  1075. }
  1076. catch (ArgumentException)
  1077. {
  1078. return false;
  1079. }
  1080. }
  1081. }
  1082. internal class MySqlConnectionStringOptionCollection : Dictionary<string, MySqlConnectionStringOption>
  1083. {
  1084. List<MySqlConnectionStringOption> options;
  1085. internal List<MySqlConnectionStringOption> Options { get { return options; } }
  1086. internal MySqlConnectionStringOptionCollection() : base( StringComparer.OrdinalIgnoreCase )
  1087. {
  1088. options = new List<MySqlConnectionStringOption>();
  1089. }
  1090. internal void Add(MySqlConnectionStringOption option)
  1091. {
  1092. options.Add(option);
  1093. // Register the option with all the keywords.
  1094. base.Add(option.Keyword, option);
  1095. if (option.Synonyms != null)
  1096. {
  1097. for (int i = 0; i < option.Synonyms.Length; i++)
  1098. base.Add(option.Synonyms[i], option);
  1099. }
  1100. }
  1101. internal MySqlConnectionStringOption Get(string keyword)
  1102. {
  1103. MySqlConnectionStringOption option = null;
  1104. base.TryGetValue(keyword, out option);
  1105. return option;
  1106. }
  1107. }
  1108. }
  1109. #endif