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.

1467 lines
62 KiB

4 years ago
  1. #if MYSQL_6_10
  2. // Copyright © 2013, 2019, 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.Data.Common;
  25. using System.Collections.Generic;
  26. using System.ComponentModel;
  27. using System.Globalization;
  28. using System.Linq;
  29. using System.Text;
  30. using System.Text.RegularExpressions;
  31. using Externals.MySql.Data.Common;
  32. using System.Reflection;
  33. using System.Runtime.CompilerServices;
  34. namespace Externals.MySql.Data.MySqlClient
  35. {
  36. /// <summary>
  37. /// Provides a base class for strongly typed connection string builders over MySQL connections.
  38. /// </summary>
  39. internal sealed class MySqlConnectionStringBuilder : DbConnectionStringBuilder
  40. {
  41. internal Dictionary<string, object> values = new Dictionary<string, object>();
  42. //internal Dictionary<string, object> values
  43. //{
  44. // get { lock (this) { return _values; } }
  45. //}
  46. private static readonly MySqlConnectionStringOptionCollection Options = new MySqlConnectionStringOptionCollection();
  47. static MySqlConnectionStringBuilder()
  48. {
  49. // Server options
  50. Options.Add(new MySqlConnectionStringOption("server", "host,data source,datasource,address,addr,network address", typeof(string), "" /*"localhost"*/, false));
  51. Options.Add(new MySqlConnectionStringOption("database", "initial catalog", typeof(string), string.Empty, false));
  52. Options.Add(new MySqlConnectionStringOption("protocol", "connection protocol,connectionprotocol", typeof(MySqlConnectionProtocol), MySqlConnectionProtocol.Sockets, false,
  53. (msb, sender, value) =>
  54. {
  55. #if NETSTANDARD1_3 || NETSTANDARD2_0 || NETCOREAPP2_2
  56. MySqlConnectionProtocol enumValue;
  57. if (Enum.TryParse<MySqlConnectionProtocol>(value.ToString(), true, out enumValue))
  58. {
  59. if (enumValue == MySqlConnectionProtocol.Memory || enumValue == MySqlConnectionProtocol.Pipe)
  60. throw new PlatformNotSupportedException(string.Format(Resources.OptionNotCurrentlySupported, $"Protocol={value}"));
  61. }
  62. #endif
  63. msb.SetValue("protocol", value);
  64. },
  65. (msb, sender) => msb.ConnectionProtocol));
  66. Options.Add(new MySqlConnectionStringOption("port", null, typeof(uint), (uint)3306, false));
  67. Options.Add(new MySqlConnectionStringOption("pipe", "pipe name,pipename", typeof(string), "MYSQL", false,
  68. (msb, sender, value) =>
  69. {
  70. #if NETSTANDARD1_3 || NETSTANDARD2_0 || NETCOREAPP2_2
  71. throw new PlatformNotSupportedException(string.Format(Resources.OptionNotCurrentlySupported, nameof(PipeName)));
  72. #else
  73. msb.SetValue("pipe", value);
  74. #endif
  75. },
  76. (msb, sender) => msb.PipeName));
  77. Options.Add(new MySqlConnectionStringOption("compress", "use compression,usecompression", typeof(bool), false, false));
  78. Options.Add(new MySqlConnectionStringOption("allowbatch", "allow batch", typeof(bool), true, false));
  79. Options.Add(new MySqlConnectionStringOption("logging", null, typeof(bool), false, false,
  80. (msb, sender, value) =>
  81. {
  82. #if NETSTANDARD1_3
  83. throw new PlatformNotSupportedException(string.Format(Resources.OptionNotCurrentlySupported, nameof(Logging)));
  84. #else
  85. msb.SetValue("logging", value);
  86. #endif
  87. },
  88. (msb, sender) => msb.Logging));
  89. Options.Add(new MySqlConnectionStringOption("sharedmemoryname", "shared memory name", typeof(string), "MYSQL", false,
  90. (msb, sender, value) =>
  91. {
  92. #if NETSTANDARD1_3 || NETSTANDARD2_0 || NETCOREAPP2_2
  93. throw new PlatformNotSupportedException(string.Format(Resources.OptionNotCurrentlySupported, nameof(SharedMemoryName)));
  94. #else
  95. msb.SetValue("sharedmemoryname", value);
  96. #endif
  97. },
  98. (msb, sender) => msb.SharedMemoryName));
  99. Options.Add(new MySqlConnectionStringOption("connectiontimeout", "connection timeout,connect timeout", typeof(uint), (uint)15, false,
  100. delegate (MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object Value)
  101. {
  102. uint value = (uint)Convert.ChangeType(Value, sender.BaseType);
  103. // Timeout in milliseconds should not exceed maximum for 32 bit
  104. // signed integer (~24 days). We truncate the value if it exceeds
  105. // maximum (MySqlCommand.CommandTimeout uses the same technique
  106. uint timeout = Math.Min(value, Int32.MaxValue / 1000);
  107. if (timeout != value)
  108. {
  109. MySqlTrace.LogWarning(-1, "Connection timeout value too large ("
  110. + value + " seconds). Changed to max. possible value" +
  111. +timeout + " seconds)");
  112. }
  113. msb.SetValue("connectiontimeout", timeout);
  114. },
  115. (msb, sender) => (uint)msb.values["connectiontimeout"]
  116. ));
  117. Options.Add(new MySqlConnectionStringOption("defaultcommandtimeout", "command timeout,default command timeout", typeof(uint), (uint)30, false));
  118. Options.Add(new MySqlConnectionStringOption("usedefaultcommandtimeoutforef", "use default command timeout for ef", typeof(bool), false, false));
  119. Options.Add(new MySqlConnectionStringOption("allowloadlocalinfile", "allow load local infile", typeof(bool), false, false));
  120. // authentication options
  121. Options.Add(new MySqlConnectionStringOption("user id", "uid,username,user name,user,userid", typeof(string), "", false));
  122. Options.Add(new MySqlConnectionStringOption("password", "pwd", typeof(string), "", false));
  123. Options.Add(new MySqlConnectionStringOption("persistsecurityinfo", "persist security info", typeof(bool), false, false));
  124. Options.Add(new MySqlConnectionStringOption("encrypt", null, typeof(bool), false, true,
  125. delegate (MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value)
  126. {
  127. // just for this case, reuse the logic to translate string to bool
  128. sender.ValidateValue(ref value);
  129. MySqlTrace.LogWarning(-1, "Encrypt is now obsolete. Use Ssl Mode instead");
  130. msb.SetValue("Ssl Mode", (bool)value ? MySqlSslMode.Prefered : MySqlSslMode.None);
  131. },
  132. (msb, sender) => msb.SslMode != MySqlSslMode.None
  133. ));
  134. Options.Add(new MySqlConnectionStringOption("certificatefile", "certificate file", typeof(string), null, false));
  135. Options.Add(new MySqlConnectionStringOption("certificatepassword", "certificate password,ssl-ca-pwd", typeof(string), null, false));
  136. Options.Add(new MySqlConnectionStringOption("certificatestorelocation", "certificate store location", typeof(MySqlCertificateStoreLocation), MySqlCertificateStoreLocation.None, false));
  137. Options.Add(new MySqlConnectionStringOption("certificatethumbprint", "certificate thumb print", typeof(string), null, false));
  138. Options.Add(new MySqlConnectionStringOption("integratedsecurity", "integrated security", typeof(bool), false, false,
  139. delegate (MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value)
  140. {
  141. if (!Platform.IsWindows())
  142. throw new MySqlException("IntegratedSecurity is supported on Windows only");
  143. #if NETSTANDARD1_3 || NETSTANDARD2_0 || NETCOREAPP2_2
  144. throw new PlatformNotSupportedException(string.Format(Resources.OptionNotCurrentlySupported, nameof(IntegratedSecurity)));
  145. #else
  146. msb.SetValue("Integrated Security", value.ToString().Equals("SSPI", StringComparison.OrdinalIgnoreCase) ? true : value);
  147. #endif
  148. },
  149. delegate (MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender)
  150. {
  151. object val = msb.values["Integrated Security"];
  152. return (bool)val;
  153. }
  154. ));
  155. Options.Add(new MySqlConnectionStringOption("allowpublickeyretrieval", "allow public key retrieval", typeof(bool), false, false));
  156. // Other properties
  157. #if !NETSTANDARD1_3
  158. Options.Add(new MySqlConnectionStringOption("autoenlist", "auto enlist", typeof(bool), true, false));
  159. Options.Add(new MySqlConnectionStringOption("includesecurityasserts", "include security asserts", typeof(bool), false, false));
  160. #endif
  161. Options.Add(new MySqlConnectionStringOption("allowzerodatetime", "allow zero datetime", typeof(bool), false, false));
  162. Options.Add(new MySqlConnectionStringOption("convertzerodatetime", "convert zero datetime", typeof(bool), false, false));
  163. Options.Add(new MySqlConnectionStringOption("useusageadvisor", "use usage advisor,usage advisor", typeof(bool), false, false,
  164. (msb, sender, value) =>
  165. {
  166. #if NETSTANDARD1_3
  167. throw new PlatformNotSupportedException(string.Format(Resources.OptionNotCurrentlySupported, nameof(UseUsageAdvisor)));
  168. #else
  169. msb.SetValue("useusageadvisor", value);
  170. #endif
  171. },
  172. (msb, sender) => msb.UseUsageAdvisor));
  173. Options.Add(new MySqlConnectionStringOption("procedurecachesize", "procedure cache size,procedure cache,procedurecache", typeof(uint), (uint)25, false));
  174. Options.Add(new MySqlConnectionStringOption("useperformancemonitor", "use performance monitor,useperfmon,perfmon", typeof(bool), false, false,
  175. (msb, sender, value) =>
  176. {
  177. #if NETSTANDARD1_3 || NETSTANDARD2_0 || NETCOREAPP2_2
  178. throw new PlatformNotSupportedException(string.Format(Resources.OptionNotCurrentlySupported, nameof(UsePerformanceMonitor)));
  179. #else
  180. msb.SetValue("useperformancemonitor", value);
  181. #endif
  182. },
  183. (msb, sender) => msb.UsePerformanceMonitor));
  184. Options.Add(new MySqlConnectionStringOption("ignoreprepare", "ignore prepare", typeof(bool), true, false));
  185. Options.Add(new MySqlConnectionStringOption("respectbinaryflags", "respect binary flags", typeof(bool), true, false));
  186. Options.Add(new MySqlConnectionStringOption("treattinyasboolean", "treat tiny as boolean", typeof(bool), true, false));
  187. Options.Add(new MySqlConnectionStringOption("allowuservariables", "allow user variables", typeof(bool), false, false));
  188. Options.Add(new MySqlConnectionStringOption("interactivesession", "interactive session,interactive", typeof(bool), false, false,
  189. (msb, sender, value) =>
  190. {
  191. #if NETSTANDARD1_3
  192. throw new PlatformNotSupportedException(string.Format(Resources.OptionNotCurrentlySupported, nameof(InteractiveSession)));
  193. #else
  194. msb.SetValue("interactivesession", value);
  195. #endif
  196. },
  197. (msb, sender) => msb.InteractiveSession));
  198. Options.Add(new MySqlConnectionStringOption("functionsreturnstring", "functions return string", typeof(bool), false, false));
  199. Options.Add(new MySqlConnectionStringOption("useaffectedrows", "use affected rows", typeof(bool), false, false));
  200. Options.Add(new MySqlConnectionStringOption("oldguids", "old guids", typeof(bool), false, false));
  201. Options.Add(new MySqlConnectionStringOption("keepalive", "keep alive", typeof(uint), (uint)0, false));
  202. Options.Add(new MySqlConnectionStringOption("sqlservermode", "sql server mode", typeof(bool), false, false));
  203. Options.Add(new MySqlConnectionStringOption("tablecaching", "table cache,tablecache", typeof(bool), false, false));
  204. Options.Add(new MySqlConnectionStringOption("defaulttablecacheage", "default table cache age", typeof(int), (int)60, false));
  205. Options.Add(new MySqlConnectionStringOption("checkparameters", "check parameters", typeof(bool), true, false));
  206. Options.Add(new MySqlConnectionStringOption("replication", null, typeof(bool), false, false,
  207. (msb, sender, value) =>
  208. {
  209. #if NETSTANDARD1_3
  210. throw new PlatformNotSupportedException(string.Format(Resources.OptionNotCurrentlySupported, nameof(Replication)));
  211. #else
  212. msb.SetValue("replication", value);
  213. #endif
  214. },
  215. (msb, sender) => msb.Replication));
  216. Options.Add(new MySqlConnectionStringOption("exceptioninterceptors", "exception interceptors", typeof(string), null, false));
  217. Options.Add(new MySqlConnectionStringOption("commandinterceptors", "command interceptors", typeof(string), null, false));
  218. // pooling options
  219. Options.Add(new MySqlConnectionStringOption("connectionlifetime", "connection lifetime", typeof(uint), (uint)0, false));
  220. Options.Add(new MySqlConnectionStringOption("pooling", null, typeof(bool), true, false));
  221. Options.Add(new MySqlConnectionStringOption("minpoolsize", "minimumpoolsize,min pool size,minimum pool size", typeof(uint), (uint)0, false));
  222. Options.Add(new MySqlConnectionStringOption("maxpoolsize", "maximumpoolsize,max pool size,maximum pool size", typeof(uint), (uint)100, false));
  223. Options.Add(new MySqlConnectionStringOption("connectionreset", "connection reset", typeof(bool), false, false));
  224. Options.Add(new MySqlConnectionStringOption("cacheserverproperties", "cache server properties", typeof(bool), false, false));
  225. // language and charset options
  226. Options.Add(new MySqlConnectionStringOption("characterset", "character set,charset", typeof(string), "", false));
  227. Options.Add(new MySqlConnectionStringOption("treatblobsasutf8", "treat blobs as utf8", typeof(bool), false, false));
  228. Options.Add(new MySqlConnectionStringOption("blobasutf8includepattern", null, typeof(string), "", false));
  229. Options.Add(new MySqlConnectionStringOption("blobasutf8excludepattern", null, typeof(string), "", false));
  230. Options.Add(new MySqlConnectionStringOption("sslmode", "ssl mode", typeof(MySqlSslMode), MySqlSslMode.Preferred, false));
  231. Options.Add(new MySqlConnectionStringOption("sslenable", "ssl-enable", typeof(bool), false, false,
  232. (msb, sender, value) => { msb.SslEnable = value is string ? bool.Parse(value as string) : (bool)value; },
  233. (msb, sender) => { return msb.SslEnable; }));
  234. Options.Add(new MySqlConnectionStringOption("sslca", "ssl-ca", typeof(string), null, false,
  235. (msb, sender, value) => { msb.SslCa = value as string; },
  236. (msb, sender) => { return msb.SslCa; }));
  237. Options.Add(new MySqlConnectionStringOption("sslcrl", "ssl-crl", typeof(string), null, false,
  238. (msb, sender, value) => { msb.SslCrl = value as string; },
  239. (msb, sender) => { return msb.SslCrl; }));
  240. }
  241. public MySqlConnectionStringBuilder()
  242. {
  243. HasProcAccess = true;
  244. // Populate initial values
  245. lock (this)
  246. {
  247. foreach (MySqlConnectionStringOption option in Options.Options)
  248. {
  249. values[option.Keyword] = option.DefaultValue;
  250. }
  251. }
  252. }
  253. public MySqlConnectionStringBuilder(string connStr)
  254. : this()
  255. {
  256. lock (this)
  257. {
  258. ConnectionString = connStr;
  259. }
  260. }
  261. #region Server Properties
  262. /// <summary>
  263. /// Gets or sets the name of the server.
  264. /// </summary>
  265. /// <value>The server.</value>
  266. [Category("Connection")]
  267. [Description("Server to connect to")]
  268. [RefreshProperties(RefreshProperties.All)]
  269. public string Server
  270. {
  271. get { return this["server"] as string; }
  272. set { SetValue("server", value); }
  273. }
  274. /// <summary>
  275. /// Gets or sets the name of the database the connection should
  276. /// initially connect to.
  277. /// </summary>
  278. [Category("Connection")]
  279. [Description("Database to use initially")]
  280. [RefreshProperties(RefreshProperties.All)]
  281. public string Database
  282. {
  283. get { return values["database"] as string; }
  284. set { SetValue("database", value); }
  285. }
  286. /// <summary>
  287. /// Gets or sets the protocol that should be used for communicating
  288. /// with MySQL.
  289. /// </summary>
  290. [Category("Connection")]
  291. [DisplayName("Connection Protocol")]
  292. [Description("Protocol to use for connection to MySQL")]
  293. [RefreshProperties(RefreshProperties.All)]
  294. public MySqlConnectionProtocol ConnectionProtocol
  295. {
  296. get { return (MySqlConnectionProtocol)values["protocol"]; }
  297. set { SetValue("protocol", value); }
  298. }
  299. /// <summary>
  300. /// Gets or sets the name of the named pipe that should be used
  301. /// for communicating with MySQL.
  302. /// </summary>
  303. [Category("Connection")]
  304. [DisplayName("Pipe Name")]
  305. [Description("Name of pipe to use when connecting with named pipes (Win32 only)")]
  306. [RefreshProperties(RefreshProperties.All)]
  307. public string PipeName
  308. {
  309. get { return (string)values["pipe"]; }
  310. set { SetValue("pipe", value); }
  311. }
  312. /// <summary>
  313. /// Gets or sets a boolean value that indicates whether this connection
  314. /// should use compression.
  315. /// </summary>
  316. [Category("Connection")]
  317. [DisplayName("Use Compression")]
  318. [Description("Should the connection use compression")]
  319. [RefreshProperties(RefreshProperties.All)]
  320. public bool UseCompression
  321. {
  322. get { return (bool)values["compress"]; }
  323. set { SetValue("compress", value); }
  324. }
  325. /// <summary>
  326. /// Gets or sets a boolean value that indicates whether this connection will allow
  327. /// commands to send multiple SQL statements in one execution.
  328. /// </summary>
  329. [Category("Connection")]
  330. [DisplayName("Allow Batch")]
  331. [Description("Allows execution of multiple SQL commands in a single statement")]
  332. [RefreshProperties(RefreshProperties.All)]
  333. public bool AllowBatch
  334. {
  335. get { return (bool)values["allowbatch"]; }
  336. set { SetValue("allowbatch", value); }
  337. }
  338. /// <summary>
  339. /// Gets or sets a boolean value that indicates whether logging is enabled.
  340. /// </summary>
  341. [Category("Connection")]
  342. [Description("Enables output of diagnostic messages")]
  343. [RefreshProperties(RefreshProperties.All)]
  344. public bool Logging
  345. {
  346. get { return (bool)values["logging"]; }
  347. set { SetValue("logging", value); }
  348. }
  349. /// <summary>
  350. /// Gets or sets the base name of the shared memory objects used to
  351. /// communicate with MySQL when the shared memory protocol is being used.
  352. /// </summary>
  353. [Category("Connection")]
  354. [DisplayName("Shared Memory Name")]
  355. [Description("Name of the shared memory object to use")]
  356. [RefreshProperties(RefreshProperties.All)]
  357. public string SharedMemoryName
  358. {
  359. get { return (string)values["sharedmemoryname"]; }
  360. set { SetValue("sharedmemoryname", value); }
  361. }
  362. /// <summary>
  363. /// Gets or sets the port number that is used when the socket
  364. /// protocol is being used.
  365. /// </summary>
  366. [Category("Connection")]
  367. [Description("Port to use for TCP/IP connections")]
  368. [RefreshProperties(RefreshProperties.All)]
  369. public uint Port
  370. {
  371. get { return (uint)values["port"]; }
  372. set { SetValue("port", value); }
  373. }
  374. /// <summary>
  375. /// Gets or sets the connection timeout.
  376. /// </summary>
  377. [Category("Connection")]
  378. [DisplayName("Connect Timeout")]
  379. [Description("The length of time (in seconds) to wait for a connection " +
  380. "to the server before terminating the attempt and generating an error.")]
  381. [RefreshProperties(RefreshProperties.All)]
  382. public uint ConnectionTimeout
  383. {
  384. get { return (uint)values["connectiontimeout"]; }
  385. set
  386. {
  387. // Timeout in milliseconds should not exceed maximum for 32 bit
  388. // signed integer (~24 days). We truncate the value if it exceeds
  389. // maximum (MySqlCommand.CommandTimeout uses the same technique
  390. uint timeout = Math.Min(value, Int32.MaxValue / 1000);
  391. if (timeout != value)
  392. {
  393. MySqlTrace.LogWarning(-1, "Connection timeout value too large ("
  394. + value + " seconds). Changed to max. possible value" +
  395. +timeout + " seconds)");
  396. }
  397. SetValue("connectiontimeout", timeout);
  398. }
  399. }
  400. /// <summary>
  401. /// Gets or sets the default command timeout.
  402. /// </summary>
  403. [Category("Connection")]
  404. [DisplayName("Default Command Timeout")]
  405. [Description(@"The default timeout that MySqlCommand objects will use
  406. unless changed.")]
  407. [RefreshProperties(RefreshProperties.All)]
  408. public uint DefaultCommandTimeout
  409. {
  410. get { return (uint)values["defaultcommandtimeout"]; }
  411. set { SetValue("defaultcommandtimeout", value); }
  412. }
  413. /// <summary>
  414. /// Gets or sets a boolean value that indicates whether this connection will allow
  415. /// to load data local infile.
  416. /// </summary>
  417. [Category("Connection")]
  418. [DisplayName("Allow Load Data Local Infile")]
  419. [Description("Allows reading data from a text file.")]
  420. [RefreshProperties(RefreshProperties.All)]
  421. public bool AllowLoadLocalInfile
  422. {
  423. get { return (bool)values["allowloadlocalinfile"]; }
  424. set { SetValue("allowloadlocalinfile", value); }
  425. }
  426. #endregion
  427. #region Authentication Properties
  428. /// <summary>
  429. /// Gets or sets the user id that should be used to connect with.
  430. /// </summary>
  431. [Category("Security")]
  432. [DisplayName("User Id")]
  433. [Description("Indicates the user ID to be used when connecting to the data source.")]
  434. [RefreshProperties(RefreshProperties.All)]
  435. public string UserID
  436. {
  437. get { return (string)values["user id"]; }
  438. set { SetValue("user id", value); }
  439. }
  440. /// <summary>
  441. /// Gets or sets the password that should be used to make a connection.
  442. /// </summary>
  443. [Category("Security")]
  444. [Description("Indicates the password to be used when connecting to the data source.")]
  445. [RefreshProperties(RefreshProperties.All)]
  446. #if !NETSTANDARD1_3
  447. [PasswordPropertyText(true)]
  448. #endif
  449. public string Password
  450. {
  451. get { return (string)values["password"]; }
  452. set { SetValue("password", value); }
  453. }
  454. /// <summary>
  455. /// Gets or sets a boolean value that indicates if the password should be persisted
  456. /// in the connection string.
  457. /// </summary>
  458. [Category("Security")]
  459. [DisplayName("Persist Security Info")]
  460. [Description("When false, security-sensitive information, such as the password, " +
  461. "is not returned as part of the connection if the connection is open or " +
  462. "has ever been in an open state.")]
  463. [RefreshProperties(RefreshProperties.All)]
  464. public bool PersistSecurityInfo
  465. {
  466. get { return (bool)values["persistsecurityinfo"]; }
  467. set { SetValue("persistsecurityinfo", value); }
  468. }
  469. /// <summary>
  470. /// Gets or sets a boolean value that indicates if the connection should be encrypted.
  471. /// </summary>
  472. /// <remarks>Obsolte. Use <see cref="SslMode"/> instead.</remarks>
  473. [Category("Authentication")]
  474. [Description("Should the connection use SSL.")]
  475. [Obsolete("Use Ssl Mode instead.")]
  476. internal bool Encrypt
  477. {
  478. get { return SslMode != MySqlSslMode.None; }
  479. set
  480. {
  481. SetValue("Ssl Mode", value ? MySqlSslMode.Prefered : MySqlSslMode.None);
  482. }
  483. }
  484. /// <summary>
  485. /// Gets or sets the path to a certificate in PKCS#12 format (.pfx).
  486. /// </summary>
  487. [Category("Authentication")]
  488. [DisplayName("Certificate File")]
  489. [Description("Certificate file in PKCS#12 format (.pfx)")]
  490. public string CertificateFile
  491. {
  492. get { return (string)values["certificatefile"]; }
  493. set { SetValue("certificatefile", value); }
  494. }
  495. /// <summary>
  496. /// Gets or sets the password associated to the certificate file.
  497. /// </summary>
  498. [Category("Authentication")]
  499. [DisplayName("Certificate Password")]
  500. [Description("Password for certificate file")]
  501. public string CertificatePassword
  502. {
  503. get { return (string)values["certificatepassword"]; }
  504. set { SetValue("certificatepassword", value); }
  505. }
  506. /// <summary>
  507. /// Gets or sets the certificate store location for client certificates.
  508. /// </summary>
  509. /// <remarks>Enables accesing a certificate held in a personal store. Default value is <see cref="MySqlCertificateStoreLocation.None"/>.</remarks>
  510. [Category("Authentication")]
  511. [DisplayName("Certificate Store Location")]
  512. [Description("Certificate Store Location for client certificates")]
  513. [DefaultValue(MySqlCertificateStoreLocation.None)]
  514. public MySqlCertificateStoreLocation CertificateStoreLocation
  515. {
  516. get { return (MySqlCertificateStoreLocation)values["certificatestorelocation"]; }
  517. set { SetValue("certificatestorelocation", value); }
  518. }
  519. /// <summary>
  520. /// Gets or sets a certificate thumbprint that can be used together with a certificate to ensure correct identification.
  521. /// </summary>
  522. [Category("Authentication")]
  523. [DisplayName("Certificate Thumbprint")]
  524. [Description("Certificate thumbprint. Can be used together with Certificate " +
  525. "Store Location parameter to uniquely identify certificate to be used " +
  526. "for SSL authentication.")]
  527. public string CertificateThumbprint
  528. {
  529. get { return (string)values["certificatethumbprint"]; }
  530. set { SetValue("certificatethumbprint", value); }
  531. }
  532. /// <summary>
  533. /// Gets or sets a boolean value that indicates if Windows authentication should be used.
  534. /// </summary>
  535. /// <remarks>Default value is <c>false</c>.</remarks>
  536. [Category("Authentication")]
  537. [DisplayName("Integrated Security")]
  538. [Description("Use windows authentication when connecting to server")]
  539. [DefaultValue(false)]
  540. public bool IntegratedSecurity
  541. {
  542. get { return (bool)values["integratedsecurity"]; }
  543. set { SetValue("integratedsecurity", value); }
  544. }
  545. /// <summary>
  546. /// Gets or sets the authentication mechanism to use with X Protocol connections.
  547. /// </summary>
  548. // /// <remarks>This option is specific to X Protocol connections. Default value is <see cref=" MySqlAuthenticationMode.Default"/>.</remarks>
  549. [Category("Authentication")]
  550. [DisplayName("Allow Public Key Retrieval")]
  551. [Description("Allow retrieval of RSA public keys when SSL is disabled")]
  552. [DefaultValue(false)]
  553. public bool AllowPublicKeyRetrieval
  554. {
  555. get { return (bool)values["allowpublickeyretrieval"]; }
  556. set { SetValue("allowpublickeyretrieval", value); }
  557. }
  558. #endregion
  559. #region Other Properties
  560. /// <summary>
  561. /// Gets or sets a boolean value that indicates if zero date time values are supported.
  562. /// </summary>
  563. /// <remarks>Default value is <c>false</c>.</remarks>
  564. [Category("Advanced")]
  565. [DisplayName("Allow Zero Datetime")]
  566. [Description("Should zero datetimes be supported")]
  567. [RefreshProperties(RefreshProperties.All)]
  568. [DefaultValue(false)]
  569. public bool AllowZeroDateTime
  570. {
  571. get { return (bool)values["allowzerodatetime"]; }
  572. set { SetValue("allowzerodatetime", value); }
  573. }
  574. /// <summary>
  575. /// Gets or sets a boolean value that indicates if zero datetime values should be
  576. /// converted to DateTime.MinValue.
  577. /// </summary>
  578. /// <remarks>Default value is <c>false</c>.</remarks>
  579. [Category("Advanced")]
  580. [DisplayName("Convert Zero Datetime")]
  581. [Description("Should illegal datetime values be converted to DateTime.MinValue")]
  582. [RefreshProperties(RefreshProperties.All)]
  583. [DefaultValue(false)]
  584. public bool ConvertZeroDateTime
  585. {
  586. get { return (bool)values["convertzerodatetime"]; }
  587. set { SetValue("convertzerodatetime", value); }
  588. }
  589. /// <summary>
  590. /// Gets or sets a boolean value that indicates if the Usage Advisor should be enabled.
  591. /// </summary>
  592. /// <remarks>Default value is <c>false</c>.</remarks>
  593. [Category("Advanced")]
  594. [DisplayName("Use Usage Advisor")]
  595. [Description("Logs inefficient database operations")]
  596. [RefreshProperties(RefreshProperties.All)]
  597. [DefaultValue(false)]
  598. public bool UseUsageAdvisor
  599. {
  600. get { return (bool)values["useusageadvisor"]; }
  601. set { SetValue("useusageadvisor", value); }
  602. }
  603. /// <summary>
  604. /// Gets or sets the size of the stored procedure cache.
  605. /// </summary>
  606. /// <remarks>Default value is 25.</remarks>
  607. [Category("Advanced")]
  608. [DisplayName("Procedure Cache Size")]
  609. [Description("Indicates how many stored procedures can be cached at one time. " +
  610. "A value of 0 effectively disables the procedure cache.")]
  611. [RefreshProperties(RefreshProperties.All)]
  612. [DefaultValue(25)]
  613. public uint ProcedureCacheSize
  614. {
  615. get { return (uint)values["procedurecachesize"]; }
  616. set { SetValue("procedurecachesize", value); }
  617. }
  618. /// <summary>
  619. /// Gets or sets a boolean value that indicates if the performance monitor hooks should be enabled.
  620. /// </summary>
  621. /// <remarks>Default value is <c>false</c>.</remarks>
  622. [Category("Advanced")]
  623. [DisplayName("Use Performance Monitor")]
  624. [Description("Indicates that performance counters should be updated during execution.")]
  625. [RefreshProperties(RefreshProperties.All)]
  626. [DefaultValue(false)]
  627. public bool UsePerformanceMonitor
  628. {
  629. get { return (bool)values["useperformancemonitor"]; }
  630. set { SetValue("useperformancemonitor", value); }
  631. }
  632. /// <summary>
  633. /// Gets or sets a boolean value that indicates if calls to the Prepare method should be ignored.
  634. /// </summary>
  635. /// <remarks>Default value is <c>false</c>.</remarks>
  636. [Category("Advanced")]
  637. [DisplayName("Ignore Prepare")]
  638. [Description("Instructs the provider to ignore any attempts to prepare a command.")]
  639. [RefreshProperties(RefreshProperties.All)]
  640. [DefaultValue(false)]
  641. public bool IgnorePrepare
  642. {
  643. get { return (bool)values["ignoreprepare"]; }
  644. set { SetValue("ignoreprepare", value); }
  645. }
  646. /// <summary>
  647. /// Gets or sets a boolean value that indicates if an opened connection should particiapte in the current scope.
  648. /// </summary>
  649. /// <remarks>Default value is <c>true</c>.</remarks>
  650. [Category("Advanced")]
  651. [DisplayName("Auto Enlist")]
  652. [Description("Should the connetion automatically enlist in the active connection, if there are any.")]
  653. [RefreshProperties(RefreshProperties.All)]
  654. [DefaultValue(true)]
  655. public bool AutoEnlist
  656. {
  657. get { return (bool)values["autoenlist"]; }
  658. set { SetValue("autoenlist", value); }
  659. }
  660. /// <summary>
  661. /// Gets or sets a boolean value that indicates if security asserts must be included.
  662. /// </summary>
  663. /// <remarks>Must be set to <c>true</c> when using the <see cref="MySqlClientPermission"/> class in a partial trust environment,
  664. /// with the library installed in the GAC of the hosting environment. Not supported in .NET Core.
  665. /// Default value is <c>false</c>.</remarks>
  666. [Category("Advanced")]
  667. [DisplayName("Include Security Asserts")]
  668. [Description("Include security asserts to support Medium Trust")]
  669. [DefaultValue(false)]
  670. public bool IncludeSecurityAsserts
  671. {
  672. get { return (bool)values["includesecurityasserts"]; }
  673. set { SetValue("includesecurityasserts", value); }
  674. }
  675. /// <summary>
  676. /// Gets or sets a boolean value that indicates if column binary flags set by the server are ignored.
  677. /// </summary>
  678. /// <remarks>Default value is <c>true</c>.</remarks>
  679. [Category("Advanced")]
  680. [DisplayName("Respect Binary Flags")]
  681. [Description("Should binary flags on column metadata be respected.")]
  682. [RefreshProperties(RefreshProperties.All)]
  683. [DefaultValue(true)]
  684. public bool RespectBinaryFlags
  685. {
  686. get { return (bool)values["respectbinaryflags"]; }
  687. set { SetValue("respectbinaryflags", value); }
  688. }
  689. /// <summary>
  690. /// Gets or sets a boolean value that indicates if <b>TINYINT(1)</b> shound be treated as a <b>BOOLEAN</b>.
  691. /// </summary>
  692. /// <remarks>Default value is <c>true</c>.</remarks>
  693. [Category("Advanced")]
  694. [DisplayName("Treat Tiny As Boolean")]
  695. [Description("Should the provider treat TINYINT(1) columns as boolean.")]
  696. [RefreshProperties(RefreshProperties.All)]
  697. [DefaultValue(true)]
  698. public bool TreatTinyAsBoolean
  699. {
  700. get { return (bool)values["treattinyasboolean"]; }
  701. set { SetValue("treattinyasboolean", value); }
  702. }
  703. /// <summary>
  704. /// Gets or sets a boolean value that indicates if the provider expects user variables in the SQL.
  705. /// </summary>
  706. /// <remarks>Default value is <c>false</c>.</remarks>
  707. [Category("Advanced")]
  708. [DisplayName("Allow User Variables")]
  709. [Description("Should the provider expect user variables to appear in the SQL.")]
  710. [RefreshProperties(RefreshProperties.All)]
  711. [DefaultValue(false)]
  712. public bool AllowUserVariables
  713. {
  714. get { return (bool)values["allowuservariables"]; }
  715. set { SetValue("allowuservariables", value); }
  716. }
  717. /// <summary>
  718. /// Gets or sets a boolean value that indicates if the session should be interactive.
  719. /// </summary>
  720. /// <remarks>Default value is <c>false</c>.</remarks>
  721. [Category("Advanced")]
  722. [DisplayName("Interactive Session")]
  723. [Description("Should this session be considered interactive?")]
  724. [RefreshProperties(RefreshProperties.All)]
  725. [DefaultValue(false)]
  726. public bool InteractiveSession
  727. {
  728. get { return (bool)values["interactivesession"]; }
  729. set { SetValue("interactivesession", value); }
  730. }
  731. /// <summary>
  732. /// Gets or sets a boolean value that indicates if server functions should be treated as returning a string.
  733. /// </summary>
  734. /// <remarks>Default value is <c>false</c>.</remarks>
  735. [Category("Advanced")]
  736. [DisplayName("Functions Return String")]
  737. [Description("Should all server functions be treated as returning string?")]
  738. [DefaultValue(false)]
  739. public bool FunctionsReturnString
  740. {
  741. get { return (bool)values["functionsreturnstring"]; }
  742. set { SetValue("functionsreturnstring", value); }
  743. }
  744. /// <summary>
  745. /// Gets or sets a boolean value that indicates if the server should report affected rows instead of found rows.
  746. /// </summary>
  747. /// <remarks>Default value is <c>false</c>.</remarks>
  748. [Category("Advanced")]
  749. [DisplayName("Use Affected Rows")]
  750. [Description("Should the returned affected row count reflect affected rows instead of found rows?")]
  751. [DefaultValue(false)]
  752. public bool UseAffectedRows
  753. {
  754. get { return (bool)values["useaffectedrows"]; }
  755. set { SetValue("useaffectedrows", value); }
  756. }
  757. /// <summary>
  758. /// Gets or sets a boolean value that indicates if items of data type <b>BINARY(16)</b> should be treated as guids.
  759. /// </summary>
  760. /// <remarks>Default value is <c>false</c>.</remarks>
  761. [Category("Advanced")]
  762. [DisplayName("Old Guids")]
  763. [Description("Treat binary(16) columns as guids")]
  764. [DefaultValue(false)]
  765. public bool OldGuids
  766. {
  767. get { return (bool)values["oldguids"]; }
  768. set { SetValue("oldguids", value); }
  769. }
  770. /// <summary>
  771. /// Gets or sets the idle connection time measured in seconds.
  772. /// </summary>
  773. /// <remarks>A value of 0 indicates that <b>Keepalive</b> is not used.</remarks>
  774. [DisplayName("Keep Alive")]
  775. [Description("For TCP connections, idle connection time measured in seconds, before the first keepalive packet is sent." +
  776. "A value of 0 indicates that keepalive is not used.")]
  777. [DefaultValue(0)]
  778. public uint Keepalive
  779. {
  780. get { return (uint)values["keepalive"]; }
  781. set { SetValue("keepalive", value); }
  782. }
  783. /// <summary>
  784. /// Gets or sets a boolean value that indicates if SQL Server syntax should be allowed by supporting square brackets
  785. /// around symbols instead of backticks.
  786. /// </summary>
  787. /// <remarks>Default value is <c>false</c>.</remarks>
  788. [Category("Advanced")]
  789. [DisplayName("Sql Server Mode")]
  790. [Description("Allow Sql Server syntax. " +
  791. "A value of yes allows symbols to be enclosed with [] instead of ``. This does incur " +
  792. "a performance hit so only use when necessary.")]
  793. [DefaultValue(false)]
  794. public bool SqlServerMode
  795. {
  796. get { return (bool)values["sqlservermode"]; }
  797. set { SetValue("sqlservermode", value); }
  798. }
  799. /// <summary>
  800. /// Gets or sets a boolean value that indicates if caching of TableDirect commands is enabled.
  801. /// </summary>
  802. /// <remarks>Default value is <c>false</c>.</remarks>
  803. [Category("Advanced")]
  804. [DisplayName("Table Cache")]
  805. [Description(@"Enables or disables caching of TableDirect command.
  806. A value of yes enables the cache while no disables it.")]
  807. [DefaultValue(false)]
  808. public bool TableCaching
  809. {
  810. get { return (bool)values["tablecaching"]; }
  811. set { SetValue("tablecachig", value); }
  812. }
  813. /// <summary>
  814. /// Gets or sets the seconds for how long a TableDirect result should be cached.
  815. /// </summary>
  816. /// <remarks>Default value is 0.</remarks>
  817. [Category("Advanced")]
  818. [DisplayName("Default Table Cache Age")]
  819. [Description(@"Specifies how long a TableDirect result should be cached in seconds.")]
  820. [DefaultValue(60)]
  821. public int DefaultTableCacheAge
  822. {
  823. get { return (int)values["defaulttablecacheage"]; }
  824. set { SetValue("defaulttablecacheage", value); }
  825. }
  826. /// <summary>
  827. /// Gets or sets a boolean value that indicates if stored routine parameters should be checked against the server.
  828. /// </summary>
  829. /// <remarks>Default value is <c>true</c>.</remarks>
  830. [Category("Advanced")]
  831. [DisplayName("Check Parameters")]
  832. [Description("Indicates if stored routine parameters should be checked against the server.")]
  833. [DefaultValue(true)]
  834. public bool CheckParameters
  835. {
  836. get { return (bool)values["checkparameters"]; }
  837. set { SetValue("checkparameters", value); }
  838. }
  839. /// <summary>
  840. /// Gets or sets a boolean value that indicates if this connection will use replication.
  841. /// </summary>
  842. /// <remarks>Default value is <c>false</c>.</remarks>
  843. [Category("Advanced")]
  844. [DisplayName("Replication")]
  845. [Description("Indicates if this connection is to use replicated servers.")]
  846. [DefaultValue(false)]
  847. public bool Replication
  848. {
  849. get { return (bool)values["replication"]; }
  850. set { SetValue("replication", value); }
  851. }
  852. /// <summary>
  853. /// Gets or sets the list of interceptors that can triage thrown MySqlExceptions.
  854. /// </summary>
  855. [Category("Advanced")]
  856. [DisplayName("Exception Interceptors")]
  857. [Description("The list of interceptors that can triage thrown MySqlExceptions.")]
  858. public string ExceptionInterceptors
  859. {
  860. get { return (string)values["exceptioninterceptors"]; }
  861. set { SetValue("exceptioninterceptors", value); }
  862. }
  863. /// <summary>
  864. /// Gets or sets the list of interceptors that can intercept command operations.
  865. /// </summary>
  866. [Category("Advanced")]
  867. [DisplayName("Command Interceptors")]
  868. [Description("The list of interceptors that can intercept command operations.")]
  869. public string CommandInterceptors
  870. {
  871. get { return (string)values["commandinterceptors"]; }
  872. set { SetValue("commandinterceptors", value); }
  873. }
  874. #endregion
  875. #region Pooling Properties
  876. /// <summary>
  877. /// Gets or sets the lifetime of a pooled connection.
  878. /// </summary>
  879. /// <remarks>Default value is 0.</remarks>
  880. [Category("Pooling")]
  881. [DisplayName("Connection Lifetime")]
  882. [Description("The minimum amount of time (in seconds) for this connection to " +
  883. "live in the pool before being destroyed.")]
  884. [RefreshProperties(RefreshProperties.All)]
  885. [DefaultValue(0)]
  886. public uint ConnectionLifeTime
  887. {
  888. get { return (uint)values["connectionlifetime"]; }
  889. set { SetValue("connectionlifetime", value); }
  890. }
  891. /// <summary>
  892. /// Gets or sets a boolean value indicating if connection pooling is enabled.
  893. /// </summary>
  894. /// <remarks>Default value is <c>true</c>.</remarks>
  895. [Category("Pooling")]
  896. [Description("When true, the connection object is drawn from the appropriate " +
  897. "pool, or if necessary, is created and added to the appropriate pool.")]
  898. [RefreshProperties(RefreshProperties.All)]
  899. [DefaultValue(true)]
  900. public bool Pooling
  901. {
  902. get { return (bool)values["pooling"]; }
  903. set { SetValue("pooling", value); }
  904. }
  905. /// <summary>
  906. /// Gets the minimum connection pool size.
  907. /// </summary>
  908. /// <remarks>Default value is 0.</remarks>
  909. [Category("Pooling")]
  910. [DisplayName("Minimum Pool Size")]
  911. [Description("The minimum number of connections allowed in the pool.")]
  912. [RefreshProperties(RefreshProperties.All)]
  913. [DefaultValue(0)]
  914. public uint MinimumPoolSize
  915. {
  916. get { return (uint)values["minpoolsize"]; }
  917. set { SetValue("minpoolsize", value); }
  918. }
  919. /// <summary>
  920. /// Gets or sets the maximum connection pool setting.
  921. /// </summary>
  922. /// <remarks>Default value is 100.</remarks>
  923. [Category("Pooling")]
  924. [DisplayName("Maximum Pool Size")]
  925. [Description("The maximum number of connections allowed in the pool.")]
  926. [RefreshProperties(RefreshProperties.All)]
  927. [DefaultValue(100)]
  928. public uint MaximumPoolSize
  929. {
  930. get { return (uint)values["maxpoolsize"]; }
  931. set { SetValue("maxpoolsize", value); }
  932. }
  933. /// <summary>
  934. /// Gets or sets a boolean value that indicates if the connection should be reset when retrieved
  935. /// from the pool.
  936. /// </summary>
  937. /// <remarks>Default value is <c>false</c>.</remarks>
  938. [Category("Pooling")]
  939. [DisplayName("Connection Reset")]
  940. [Description("When true, indicates the connection state is reset when removed from the pool.")]
  941. [RefreshProperties(RefreshProperties.All)]
  942. [DefaultValue(false)]
  943. public bool ConnectionReset
  944. {
  945. get { return (bool)values["connectionreset"]; }
  946. set { SetValue("connectionreset", value); }
  947. }
  948. /// <summary>
  949. /// Gets or sets a boolean value that indicates whether the server variable settings are updated by a
  950. /// SHOW VARIABLES command each time a pooled connection is returned.
  951. /// </summary>
  952. /// <remarks>Default value is <c>false</c>.</remarks>
  953. [Category("Pooling")]
  954. [DisplayName("Cache Server Properties")]
  955. [Description("When true, server properties will be cached after the first server in the pool is created")]
  956. [RefreshProperties(RefreshProperties.All)]
  957. [DefaultValue(false)]
  958. public bool CacheServerProperties
  959. {
  960. get { return (bool)values["cacheserverproperties"]; }
  961. set { SetValue("cacheserverproperties", value); }
  962. }
  963. #endregion
  964. #region Language and Character Set Properties
  965. /// <summary>
  966. /// Gets or sets the character set that should be used for sending queries to the server.
  967. /// </summary>
  968. /// <remarks>Default value is an empty string.</remarks>
  969. [DisplayName("Character Set")]
  970. [Category("Advanced")]
  971. [Description("Character set this connection should use")]
  972. [RefreshProperties(RefreshProperties.All)]
  973. [DefaultValue("")]
  974. public string CharacterSet
  975. {
  976. get { return (string)values["characterset"]; }
  977. set { SetValue("characterset", value); }
  978. }
  979. /// <summary>
  980. /// Indicates whether the driver should treat binary BLOBs as UTF8.
  981. /// </summary>
  982. /// <remarks>Default value is <c>false</c>.</remarks>
  983. [DisplayName("Treat Blobs As UTF8")]
  984. [Category("Advanced")]
  985. [Description("Should binary blobs be treated as UTF8")]
  986. [RefreshProperties(RefreshProperties.All)]
  987. [DefaultValue(false)]
  988. public bool TreatBlobsAsUTF8
  989. {
  990. get { return (bool)values["treatblobsasutf8"]; }
  991. set { SetValue("treatblobsasutf8", value); }
  992. }
  993. /// <summary>
  994. /// Gets or sets the pattern to match for the columns that should be treated as UTF8.
  995. /// </summary>
  996. [Category("Advanced")]
  997. [Description("Pattern that matches columns that should be treated as UTF8")]
  998. [RefreshProperties(RefreshProperties.All)]
  999. public string BlobAsUTF8IncludePattern
  1000. {
  1001. get { return (string)values["blobasutf8includepattern"]; }
  1002. set { SetValue("blobasutf8includepattern", value); }
  1003. }
  1004. /// <summary>
  1005. /// Gets or sets the pattern to match for the columns that should not be treated as UTF8.
  1006. /// </summary>
  1007. [Category("Advanced")]
  1008. [Description("Pattern that matches columns that should not be treated as UTF8")]
  1009. [RefreshProperties(RefreshProperties.All)]
  1010. public string BlobAsUTF8ExcludePattern
  1011. {
  1012. get { return (string)values["blobasutf8excludepattern"]; }
  1013. set { SetValue("blobasutf8excludepattern", value); }
  1014. }
  1015. /// <summary>
  1016. /// Indicates whether to use SSL connections and how to handle server certificate errors.
  1017. /// </summary>
  1018. /// <remarks>Default value is <see cref="MySqlSslMode.Prefered"/>.</remarks>
  1019. [DisplayName("Ssl Mode")]
  1020. [Category("Security")]
  1021. [Description("SSL properties for connection")]
  1022. [DefaultValue(MySqlSslMode.Prefered)]
  1023. public MySqlSslMode SslMode
  1024. {
  1025. get { return (MySqlSslMode)values["sslmode"]; }
  1026. set { SetValue("sslmode", value); }
  1027. }
  1028. #endregion
  1029. #region Backwards compatibility properties
  1030. /// <summary>
  1031. /// Gets or sets a boolean value that indicates if the command timeout of <b>EFMySqlCommand</b> should be
  1032. /// enforced to the value provided in the <see cref="DefaultCommandTimeout"/> property.
  1033. /// </summary>
  1034. /// <remarks>Default value is <c>false</c>.</remarks>
  1035. [DisplayName("Use Default Command Timeout For EF")]
  1036. [Category("Backwards Compatibility")]
  1037. [Description("Enforces the command timeout of EFMySqlCommand to the value provided in 'DefaultCommandTimeout' property")]
  1038. [DefaultValue(false)]
  1039. public bool UseDefaultCommandTimeoutForEF
  1040. {
  1041. get { return (bool)values["usedefaultcommandtimeoutforef"]; }
  1042. set { SetValue("usedefaultcommandtimeoutforef", value); }
  1043. }
  1044. #endregion
  1045. #region XProperties
  1046. /// <summary>
  1047. /// Gets or sets a boolean value that indicates if SSL is enabled.
  1048. /// </summary>
  1049. /// <remarks>Default value is <c>false</c>.</remarks>
  1050. [Description("Enables the use of SSL as required")]
  1051. public bool SslEnable
  1052. {
  1053. get { return ((MySqlSslMode)this["sslmode"] != MySqlSslMode.None); }
  1054. set
  1055. {
  1056. if (value)
  1057. SslMode = MySqlSslMode.Required;
  1058. else
  1059. SslMode = MySqlSslMode.None;
  1060. }
  1061. }
  1062. /// <summary>
  1063. /// Gets or sets the path to a local file that contains a list of trusted Certificate Authorities.
  1064. /// </summary>
  1065. [Description("Path to a local file that contains a list of trusted TLS/SSL CAs")]
  1066. public string SslCa
  1067. {
  1068. get { return CertificateFile; }
  1069. set
  1070. {
  1071. SslEnable = true;
  1072. CertificateFile = value;
  1073. }
  1074. }
  1075. /// <summary>
  1076. /// Gets or sets the path to a local file that contains certificate revocation lists.
  1077. /// </summary>
  1078. [Description("Path to a local file that contains certificate revocation lists")]
  1079. public string SslCrl
  1080. {
  1081. get { throw new NotSupportedException(); }
  1082. set { throw new NotSupportedException(); }
  1083. }
  1084. #endregion
  1085. internal bool HasProcAccess { get; set; }
  1086. public override object this[string keyword]
  1087. {
  1088. get { MySqlConnectionStringOption opt = GetOption(keyword); return opt.Getter(this, opt); }
  1089. set { MySqlConnectionStringOption opt = GetOption(keyword); opt.Setter(this, opt, value); }
  1090. }
  1091. internal Regex GetBlobAsUTF8IncludeRegex()
  1092. {
  1093. if (String.IsNullOrEmpty(BlobAsUTF8IncludePattern)) return null;
  1094. return new Regex(BlobAsUTF8IncludePattern);
  1095. }
  1096. internal Regex GetBlobAsUTF8ExcludeRegex()
  1097. {
  1098. if (String.IsNullOrEmpty(BlobAsUTF8ExcludePattern)) return null;
  1099. return new Regex(BlobAsUTF8ExcludePattern);
  1100. }
  1101. public override void Clear()
  1102. {
  1103. base.Clear();
  1104. lock (this)
  1105. {
  1106. foreach (var option in Options.Options)
  1107. if (option.DefaultValue != null)
  1108. values[option.Keyword] = option.DefaultValue;
  1109. else
  1110. values[option.Keyword] = null;
  1111. }
  1112. }
  1113. #if NET40
  1114. private void SetValue(string keyword, object value, string callerName = "")
  1115. #else
  1116. private void SetValue(string keyword, object value, [CallerMemberName] string callerName = "")
  1117. #endif
  1118. {
  1119. MySqlConnectionStringOption option = GetOption(keyword);
  1120. if (callerName != ".cctor" && option.IsCustomized)
  1121. this[keyword] = value;
  1122. else
  1123. SetInternalValue(keyword, value);
  1124. }
  1125. internal void SetInternalValue(string keyword, object value)
  1126. {
  1127. MySqlConnectionStringOption option = GetOption(keyword);
  1128. option.ValidateValue(ref value);
  1129. // remove all related keywords
  1130. option.Clean(this);
  1131. if (value != null)
  1132. {
  1133. lock (this)
  1134. {
  1135. // set value for the given keyword
  1136. values[option.Keyword] = value;
  1137. base[keyword] = value;
  1138. }
  1139. }
  1140. }
  1141. private MySqlConnectionStringOption GetOption(string key)
  1142. {
  1143. MySqlConnectionStringOption option = Options.Get(key);
  1144. if (option == null)
  1145. throw new ArgumentException(Resources.KeywordNotSupported, key);
  1146. else
  1147. return option;
  1148. }
  1149. public override bool ContainsKey(string keyword)
  1150. {
  1151. MySqlConnectionStringOption option = Options.Get(keyword);
  1152. return option != null;
  1153. }
  1154. public override bool Remove(string keyword)
  1155. {
  1156. bool removed = false;
  1157. lock (this) { removed = base.Remove(keyword); }
  1158. if (!removed) return false;
  1159. MySqlConnectionStringOption option = GetOption(keyword);
  1160. lock (this)
  1161. {
  1162. values[option.Keyword] = option.DefaultValue;
  1163. }
  1164. return true;
  1165. }
  1166. /// <summary>
  1167. /// Gets the connection string.
  1168. /// </summary>
  1169. /// <param name="includePass">A flag indicating if the returned connection string should include the password of the user.</param>
  1170. /// <returns>The connection string.</returns>
  1171. public string GetConnectionString(bool includePass)
  1172. {
  1173. if (includePass) return ConnectionString;
  1174. StringBuilder conn = new StringBuilder();
  1175. string delimiter = "";
  1176. foreach (string key in this.Keys)
  1177. {
  1178. if (String.Compare(key, "password", StringComparison.OrdinalIgnoreCase) == 0 ||
  1179. String.Compare(key, "pwd", StringComparison.OrdinalIgnoreCase) == 0) continue;
  1180. conn.AppendFormat(CultureInfo.CurrentCulture, "{0}{1}={2}",
  1181. delimiter, key, this[key]);
  1182. delimiter = ";";
  1183. }
  1184. return conn.ToString();
  1185. }
  1186. public override bool Equals(object obj)
  1187. {
  1188. MySqlConnectionStringBuilder other = obj as MySqlConnectionStringBuilder;
  1189. if (obj == null)
  1190. return false;
  1191. if (this.values.Count != other.values.Count) return false;
  1192. foreach (KeyValuePair<string, object> kvp in this.values)
  1193. {
  1194. if (other.values.ContainsKey(kvp.Key))
  1195. {
  1196. object v = other.values[kvp.Key];
  1197. if (v == null && kvp.Value != null) return false;
  1198. if (kvp.Value == null && v != null) return false;
  1199. if (kvp.Value == null && v == null) return true;
  1200. if (!v.Equals(kvp.Value)) return false;
  1201. }
  1202. else
  1203. {
  1204. return false;
  1205. }
  1206. }
  1207. return true;
  1208. }
  1209. public override int GetHashCode()
  1210. {
  1211. return base.GetHashCode();
  1212. }
  1213. }
  1214. class MySqlConnectionStringOption
  1215. {
  1216. public bool IsCustomized { get; }
  1217. public MySqlConnectionStringOption(string keyword, string synonyms, Type baseType, object defaultValue, bool obsolete,
  1218. SetterDelegate setter, GetterDelegate getter)
  1219. {
  1220. Keyword = StringUtility.ToLowerInvariant(keyword);
  1221. if (synonyms != null)
  1222. Synonyms = StringUtility.ToLowerInvariant(synonyms).Split(',');
  1223. BaseType = baseType;
  1224. Obsolete = obsolete;
  1225. DefaultValue = defaultValue;
  1226. Setter = setter;
  1227. Getter = getter;
  1228. IsCustomized = true;
  1229. }
  1230. public MySqlConnectionStringOption(string keyword, string synonyms, Type baseType, object defaultValue, bool obsolete) :
  1231. this(keyword, synonyms, baseType, defaultValue, obsolete,
  1232. delegate (MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value)
  1233. {
  1234. sender.ValidateValue(ref value);
  1235. //if ( sender.BaseType.IsEnum )
  1236. // msb.SetValue( sender.Keyword, Enum.Parse( sender.BaseType, ( string )value, true ));
  1237. //else
  1238. msb.SetInternalValue(sender.Keyword, Convert.ChangeType(value, sender.BaseType));
  1239. },
  1240. (msb, sender) => msb.values[sender.Keyword]
  1241. )
  1242. {
  1243. IsCustomized = false;
  1244. }
  1245. public string[] Synonyms { get; private set; }
  1246. public bool Obsolete { get; private set; }
  1247. public Type BaseType { get; private set; }
  1248. public string Keyword { get; private set; }
  1249. public object DefaultValue { get; private set; }
  1250. public SetterDelegate Setter { get; private set; }
  1251. public GetterDelegate Getter { get; private set; }
  1252. internal delegate void SetterDelegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender, object value);
  1253. internal delegate object GetterDelegate(MySqlConnectionStringBuilder msb, MySqlConnectionStringOption sender);
  1254. public bool HasKeyword(string key)
  1255. {
  1256. if (Keyword == key) return true;
  1257. if (Synonyms == null) return false;
  1258. return Synonyms.Any(syn => syn == key);
  1259. }
  1260. public void Clean(MySqlConnectionStringBuilder builder)
  1261. {
  1262. builder.Remove(Keyword);
  1263. if (Synonyms == null) return;
  1264. foreach (var syn in Synonyms)
  1265. builder.Remove(syn);
  1266. }
  1267. public void ValidateValue(ref object value)
  1268. {
  1269. bool b;
  1270. if (value == null) return;
  1271. string typeName = BaseType.Name;
  1272. Type valueType = value.GetType();
  1273. if (valueType.Name == "String")
  1274. {
  1275. if (BaseType == valueType) return;
  1276. else if (BaseType == typeof(bool))
  1277. {
  1278. if (string.Compare("yes", (string)value, StringComparison.OrdinalIgnoreCase) == 0) value = true;
  1279. else if (string.Compare("no", (string)value, StringComparison.OrdinalIgnoreCase) == 0) value = false;
  1280. else if (Boolean.TryParse(value.ToString(), out b)) value = b;
  1281. else throw new ArgumentException(String.Format(Resources.ValueNotCorrectType, value));
  1282. return;
  1283. }
  1284. }
  1285. if (typeName == "Boolean" && Boolean.TryParse(value.ToString(), out b)) { value = b; return; }
  1286. UInt64 uintVal;
  1287. if (typeName.StartsWith("UInt64") && UInt64.TryParse(value.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out uintVal)) { value = uintVal; return; }
  1288. UInt32 uintVal32;
  1289. if (typeName.StartsWith("UInt32") && UInt32.TryParse(value.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out uintVal32)) { value = uintVal32; return; }
  1290. Int64 intVal;
  1291. if (typeName.StartsWith("Int64") && Int64.TryParse(value.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out intVal)) { value = intVal; return; }
  1292. Int32 intVal32;
  1293. if (typeName.StartsWith("Int32") && Int32.TryParse(value.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out intVal32)) { value = intVal32; return; }
  1294. object objValue;
  1295. Type baseType = BaseType.GetTypeInfo().BaseType;
  1296. if (baseType != null && baseType.Name == "Enum" && ParseEnum(value.ToString(), out objValue))
  1297. {
  1298. value = objValue; return;
  1299. }
  1300. throw new ArgumentException(String.Format(Resources.ValueNotCorrectType, value));
  1301. }
  1302. private bool ParseEnum(string requestedValue, out object value)
  1303. {
  1304. value = null;
  1305. try
  1306. {
  1307. value = Enum.Parse(BaseType, requestedValue, true);
  1308. return true;
  1309. }
  1310. catch (ArgumentException)
  1311. {
  1312. return false;
  1313. }
  1314. }
  1315. }
  1316. internal class MySqlConnectionStringOptionCollection : Dictionary<string, MySqlConnectionStringOption>
  1317. {
  1318. internal List<MySqlConnectionStringOption> Options { get; }
  1319. internal MySqlConnectionStringOptionCollection() : base(StringComparer.OrdinalIgnoreCase)
  1320. {
  1321. Options = new List<MySqlConnectionStringOption>();
  1322. }
  1323. internal void Add(MySqlConnectionStringOption option)
  1324. {
  1325. Options.Add(option);
  1326. // Register the option with all the keywords.
  1327. base.Add(option.Keyword, option);
  1328. if (option.Synonyms == null) return;
  1329. foreach (string t in option.Synonyms)
  1330. base.Add(t, option);
  1331. }
  1332. internal MySqlConnectionStringOption Get(string keyword)
  1333. {
  1334. MySqlConnectionStringOption option = null;
  1335. base.TryGetValue(keyword, out option);
  1336. return option;
  1337. }
  1338. }
  1339. }
  1340. #endif