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.

1133 lines
36 KiB

  1. // Copyright ?2004, 2014, Oracle and/or its affiliates. All rights reserved.
  2. //
  3. // MySQL Connector/NET is licensed under the terms of the GPLv2
  4. // <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
  5. // MySQL Connectors. There are special exceptions to the terms and
  6. // conditions of the GPLv2 as it is applied to this software, see the
  7. // FLOSS License Exception
  8. // <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
  9. //
  10. // This program is free software; you can redistribute it and/or modify
  11. // it under the terms of the GNU General Public License as published
  12. // by the Free Software Foundation; version 2 of the License.
  13. //
  14. // This program is distributed in the hope that it will be useful, but
  15. // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  16. // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  17. // for more details.
  18. //
  19. // You should have received a copy of the GNU General Public License along
  20. // with this program; if not, write to the Free Software Foundation, Inc.,
  21. // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22. #if NET40 || NET461
  23. using System;
  24. using System.Data;
  25. using System.Data.Common;
  26. using System.ComponentModel;
  27. using System.Collections.Generic;
  28. #if NET40 || NET461
  29. using System.Threading.Tasks;
  30. using System.Threading;
  31. #endif
  32. namespace Externals.MySql.Data.MySqlClient
  33. {
  34. /// <include file='Externals/MySql.Data-6.9.11/docs/mysqlDataAdapter.xml' path='docs/class/*'/>
  35. [System.Drawing.ToolboxBitmap(typeof(MySqlDataAdapter), "MySqlClient.resources.dataadapter.bmp")]
  36. [System.ComponentModel.DesignerCategory("Code")]
  37. [Designer("Externals.MySql.Data.MySqlClient.Design.MySqlDataAdapterDesigner,MySqlClient.Design")]
  38. internal sealed class MySqlDataAdapter : DbDataAdapter, IDbDataAdapter, IDataAdapter, ICloneable
  39. {
  40. private bool loadingDefaults;
  41. private int updateBatchSize;
  42. List<IDbCommand> commandBatch;
  43. /// <summary>
  44. /// Occurs during Update before a command is executed against the data source. The attempt to update is made, so the event fires.
  45. /// </summary>
  46. public event MySqlRowUpdatingEventHandler RowUpdating;
  47. /// <summary>
  48. /// Occurs during Update after a command is executed against the data source. The attempt to update is made, so the event fires.
  49. /// </summary>
  50. public event MySqlRowUpdatedEventHandler RowUpdated;
  51. /// <include file='Externals/MySql.Data-6.9.11/docs/mysqlDataAdapter.xml' path='docs/Ctor/*'/>
  52. public MySqlDataAdapter()
  53. {
  54. loadingDefaults = true;
  55. updateBatchSize = 1;
  56. }
  57. /// <include file='Externals/MySql.Data-6.9.11/docs/mysqlDataAdapter.xml' path='docs/Ctor1/*'/>
  58. public MySqlDataAdapter(MySqlCommand selectCommand)
  59. : this()
  60. {
  61. SelectCommand = selectCommand;
  62. }
  63. public MySqlDataAdapter(string selectCommandText, MySqlConnection connection)
  64. : this()
  65. {
  66. SelectCommand = new MySqlCommand(selectCommandText, connection);
  67. }
  68. /// <include file='Externals/MySql.Data-6.9.11/docs/mysqlDataAdapter.xml' path='docs/Ctor3/*'/>
  69. public MySqlDataAdapter(string selectCommandText, string selectConnString)
  70. : this()
  71. {
  72. SelectCommand = new MySqlCommand(selectCommandText,
  73. new MySqlConnection(selectConnString));
  74. }
  75. #region Properties
  76. /// <include file='Externals/MySql.Data-6.9.11/docs/mysqlDataAdapter.xml' path='docs/DeleteCommand/*'/>
  77. [Description("Used during Update for deleted rows in Dataset.")]
  78. public new MySqlCommand DeleteCommand
  79. {
  80. get { return (MySqlCommand)base.DeleteCommand; }
  81. set { base.DeleteCommand = value; }
  82. }
  83. /// <include file='Externals/MySql.Data-6.9.11/docs/mysqlDataAdapter.xml' path='docs/InsertCommand/*'/>
  84. [Description("Used during Update for new rows in Dataset.")]
  85. public new MySqlCommand InsertCommand
  86. {
  87. get { return (MySqlCommand)base.InsertCommand; }
  88. set { base.InsertCommand = value; }
  89. }
  90. /// <include file='Externals/MySql.Data-6.9.11/docs/mysqlDataAdapter.xml' path='docs/SelectCommand/*'/>
  91. [Description("Used during Fill/FillSchema")]
  92. [Category("Fill")]
  93. public new MySqlCommand SelectCommand
  94. {
  95. get { return (MySqlCommand)base.SelectCommand; }
  96. set { base.SelectCommand = value; }
  97. }
  98. /// <include file='Externals/MySql.Data-6.9.11/docs/mysqlDataAdapter.xml' path='docs/UpdateCommand/*'/>
  99. [Description("Used during Update for modified rows in Dataset.")]
  100. public new MySqlCommand UpdateCommand
  101. {
  102. get { return (MySqlCommand)base.UpdateCommand; }
  103. set { base.UpdateCommand = value; }
  104. }
  105. internal bool LoadDefaults
  106. {
  107. get { return loadingDefaults; }
  108. set { loadingDefaults = value; }
  109. }
  110. #endregion
  111. /// <summary>
  112. /// Open connection if it was closed.
  113. /// Necessary to workaround "connection must be open and valid" error
  114. /// with batched updates.
  115. /// </summary>
  116. /// <param name="state">Row state</param>
  117. /// <param name="openedConnections"> list of opened connections
  118. /// If connection is opened by this function, the list is updated
  119. /// </param>
  120. /// <returns>true if connection was opened</returns>
  121. private void OpenConnectionIfClosed(DataRowState state,
  122. List<MySqlConnection> openedConnections)
  123. {
  124. MySqlCommand cmd = null;
  125. switch (state)
  126. {
  127. case DataRowState.Added:
  128. cmd = InsertCommand;
  129. break;
  130. case DataRowState.Deleted:
  131. cmd = DeleteCommand;
  132. break;
  133. case DataRowState.Modified:
  134. cmd = UpdateCommand;
  135. break;
  136. default:
  137. return;
  138. }
  139. if (cmd != null && cmd.Connection != null &&
  140. cmd.Connection.connectionState == ConnectionState.Closed)
  141. {
  142. cmd.Connection.Open();
  143. openedConnections.Add(cmd.Connection);
  144. }
  145. }
  146. protected override int Update(DataRow[] dataRows, DataTableMapping tableMapping)
  147. {
  148. List<MySqlConnection> connectionsOpened = new List<MySqlConnection>();
  149. try
  150. {
  151. // Open connections for insert/update/update commands, if
  152. // connections are closed.
  153. foreach (DataRow row in dataRows)
  154. {
  155. OpenConnectionIfClosed(row.RowState, connectionsOpened);
  156. }
  157. int ret = base.Update(dataRows, tableMapping);
  158. return ret;
  159. }
  160. finally
  161. {
  162. foreach (MySqlConnection c in connectionsOpened)
  163. c.Close();
  164. }
  165. }
  166. #region Batching Support
  167. public override int UpdateBatchSize
  168. {
  169. get { return updateBatchSize; }
  170. set { updateBatchSize = value; }
  171. }
  172. protected override void InitializeBatching()
  173. {
  174. commandBatch = new List<IDbCommand>();
  175. }
  176. protected override int AddToBatch(IDbCommand command)
  177. {
  178. // the first time each command is asked to be batched, we ask
  179. // that command to prepare its batchable command text. We only want
  180. // to do this one time for each command
  181. MySqlCommand commandToBatch = (MySqlCommand)command;
  182. if (commandToBatch.BatchableCommandText == null)
  183. commandToBatch.GetCommandTextForBatching();
  184. IDbCommand cloneCommand = (IDbCommand)((ICloneable)command).Clone();
  185. commandBatch.Add(cloneCommand);
  186. return commandBatch.Count - 1;
  187. }
  188. protected override int ExecuteBatch()
  189. {
  190. int recordsAffected = 0;
  191. int index = 0;
  192. while (index < commandBatch.Count)
  193. {
  194. MySqlCommand cmd = (MySqlCommand)commandBatch[index++];
  195. for (int index2 = index; index2 < commandBatch.Count; index2++, index++)
  196. {
  197. MySqlCommand cmd2 = (MySqlCommand)commandBatch[index2];
  198. if (cmd2.BatchableCommandText == null ||
  199. cmd2.CommandText != cmd.CommandText) break;
  200. cmd.AddToBatch(cmd2);
  201. }
  202. recordsAffected += cmd.ExecuteNonQuery();
  203. }
  204. return recordsAffected;
  205. }
  206. protected override void ClearBatch()
  207. {
  208. if (commandBatch.Count > 0)
  209. {
  210. MySqlCommand cmd = (MySqlCommand)commandBatch[0];
  211. if (cmd.Batch != null)
  212. cmd.Batch.Clear();
  213. }
  214. commandBatch.Clear();
  215. }
  216. protected override void TerminateBatching()
  217. {
  218. ClearBatch();
  219. commandBatch = null;
  220. }
  221. protected override IDataParameter GetBatchedParameter(int commandIdentifier, int parameterIndex)
  222. {
  223. return (IDataParameter)commandBatch[commandIdentifier].Parameters[parameterIndex];
  224. }
  225. #endregion
  226. /// <summary>
  227. /// Overridden. See <see cref="DbDataAdapter.CreateRowUpdatedEvent"/>.
  228. /// </summary>
  229. /// <param name="dataRow"></param>
  230. /// <param name="command"></param>
  231. /// <param name="statementType"></param>
  232. /// <param name="tableMapping"></param>
  233. /// <returns></returns>
  234. override protected RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
  235. {
  236. return new MySqlRowUpdatedEventArgs(dataRow, command, statementType, tableMapping);
  237. }
  238. /// <summary>
  239. /// Overridden. See <see cref="DbDataAdapter.CreateRowUpdatingEvent"/>.
  240. /// </summary>
  241. /// <param name="dataRow"></param>
  242. /// <param name="command"></param>
  243. /// <param name="statementType"></param>
  244. /// <param name="tableMapping"></param>
  245. /// <returns></returns>
  246. override protected RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
  247. {
  248. return new MySqlRowUpdatingEventArgs(dataRow, command, statementType, tableMapping);
  249. }
  250. /// <summary>
  251. /// Overridden. Raises the RowUpdating event.
  252. /// </summary>
  253. /// <param name="value">A MySqlRowUpdatingEventArgs that contains the event data.</param>
  254. override protected void OnRowUpdating(RowUpdatingEventArgs value)
  255. {
  256. if (RowUpdating != null)
  257. RowUpdating(this, (value as MySqlRowUpdatingEventArgs));
  258. }
  259. /// <summary>
  260. /// Overridden. Raises the RowUpdated event.
  261. /// </summary>
  262. /// <param name="value">A MySqlRowUpdatedEventArgs that contains the event data. </param>
  263. override protected void OnRowUpdated(RowUpdatedEventArgs value)
  264. {
  265. if (RowUpdated != null)
  266. RowUpdated(this, (value as MySqlRowUpdatedEventArgs));
  267. }
  268. #if NET40 || NET461
  269. #region Async
  270. #region Fill
  271. /// <summary>
  272. /// Async version of Fill
  273. /// </summary>
  274. /// <param name="dataSet">Dataset to use</param>
  275. /// <returns>int</returns>
  276. public Task<int> FillAsync(DataSet dataSet)
  277. {
  278. return FillAsync(dataSet, CancellationToken.None);
  279. }
  280. public Task<int> FillAsync(DataSet dataSet, CancellationToken cancellationToken)
  281. {
  282. var result = new TaskCompletionSource<int>();
  283. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  284. {
  285. try
  286. {
  287. var fillResult = base.Fill(dataSet);
  288. result.SetResult(fillResult);
  289. }
  290. catch (Exception ex)
  291. {
  292. result.SetException(ex);
  293. }
  294. }
  295. else
  296. {
  297. result.SetCanceled();
  298. }
  299. return result.Task;
  300. }
  301. /// <summary>
  302. /// Async version of Fill
  303. /// </summary>
  304. /// <param name="dataTable">Datatable to use</param>
  305. /// <returns>int</returns>
  306. public Task<int> FillAsync(DataTable dataTable)
  307. {
  308. return FillAsync(dataTable, CancellationToken.None);
  309. }
  310. public Task<int> FillAsync(DataTable dataTable, CancellationToken cancellationToken)
  311. {
  312. var result = new TaskCompletionSource<int>();
  313. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  314. {
  315. try
  316. {
  317. var fillResult = base.Fill(dataTable);
  318. result.SetResult(fillResult);
  319. }
  320. catch (Exception ex)
  321. {
  322. result.SetException(ex);
  323. }
  324. }
  325. else
  326. {
  327. result.SetCanceled();
  328. }
  329. return result.Task;
  330. }
  331. /// <summary>
  332. /// Async version of Fill
  333. /// </summary>
  334. /// <param name="dataSet">DataSet to use</param>
  335. /// <param name="srcTable">Source table</param>
  336. /// <returns>int</returns>
  337. public Task<int> FillAsync(DataSet dataSet, string srcTable)
  338. {
  339. return FillAsync(dataSet, srcTable, CancellationToken.None);
  340. }
  341. public Task<int> FillAsync(DataSet dataSet, string srcTable, CancellationToken cancellationToken)
  342. {
  343. var result = new TaskCompletionSource<int>();
  344. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  345. {
  346. try
  347. {
  348. var fillResult = base.Fill(dataSet, srcTable);
  349. result.SetResult(fillResult);
  350. }
  351. catch (Exception ex)
  352. {
  353. result.SetException(ex);
  354. }
  355. }
  356. else
  357. {
  358. result.SetCanceled();
  359. }
  360. return result.Task;
  361. }
  362. /// <summary>
  363. /// Async version of Fill
  364. /// </summary>
  365. /// <param name="dataTable">Datatable to use</param>
  366. /// <param name="dataReader">DataReader to use</param>
  367. /// <returns>int</returns>
  368. public Task<int> FillAsync(DataTable dataTable, IDataReader dataReader)
  369. {
  370. return FillAsync(dataTable, dataReader, CancellationToken.None);
  371. }
  372. public Task<int> FillAsync(DataTable dataTable, IDataReader dataReader, CancellationToken cancellationToken)
  373. {
  374. var result = new TaskCompletionSource<int>();
  375. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  376. {
  377. try
  378. {
  379. var fillResult = base.Fill(dataTable, dataReader);
  380. result.SetResult(fillResult);
  381. }
  382. catch (Exception ex)
  383. {
  384. result.SetException(ex);
  385. }
  386. }
  387. else
  388. {
  389. result.SetCanceled();
  390. }
  391. return result.Task;
  392. }
  393. /// <summary>
  394. /// Async version of Fill
  395. /// </summary>
  396. /// <param name="dataTable">DataTable to use</param>
  397. /// <param name="command">DbCommand to use</param>
  398. /// <param name="behavior">Command Behavior</param>
  399. /// <returns>int</returns>
  400. public Task<int> FillAsync(DataTable dataTable, IDbCommand command, CommandBehavior behavior)
  401. {
  402. return FillAsync(dataTable, command, behavior, CancellationToken.None);
  403. }
  404. public Task<int> FillAsync(DataTable dataTable, IDbCommand command, CommandBehavior behavior, CancellationToken cancellationToken)
  405. {
  406. var result = new TaskCompletionSource<int>();
  407. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  408. {
  409. try
  410. {
  411. var fillResult = base.Fill(dataTable, command, behavior);
  412. result.SetResult(fillResult);
  413. }
  414. catch (Exception ex)
  415. {
  416. result.SetException(ex);
  417. }
  418. }
  419. else
  420. {
  421. result.SetCanceled();
  422. }
  423. return result.Task;
  424. }
  425. /// <summary>
  426. /// Async version of Fill
  427. /// </summary>
  428. /// <param name="startRecord">Start record</param>
  429. /// <param name="maxRecords">Max records</param>
  430. /// <param name="dataTables">DataTable[] to use</param>
  431. /// <returns>int</returns>
  432. public Task<int> FillAsync(int startRecord, int maxRecords, params DataTable[] dataTables)
  433. {
  434. return FillAsync(startRecord, maxRecords, CancellationToken.None, dataTables);
  435. }
  436. public Task<int> FillAsync(int startRecord, int maxRecords, CancellationToken cancellationToken, params DataTable[] dataTables)
  437. {
  438. var result = new TaskCompletionSource<int>();
  439. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  440. {
  441. try
  442. {
  443. var fillResult = base.Fill(startRecord, maxRecords, dataTables);
  444. result.SetResult(fillResult);
  445. }
  446. catch (Exception ex)
  447. {
  448. result.SetException(ex);
  449. }
  450. }
  451. else
  452. {
  453. result.SetCanceled();
  454. }
  455. return result.Task;
  456. }
  457. /// <summary>
  458. /// Async version of Fill
  459. /// </summary>
  460. /// <param name="dataSet">DataSet to use</param>
  461. /// <param name="startRecord">Start record</param>
  462. /// <param name="maxRecords">Max records</param>
  463. /// <param name="srcTable">Source table</param>
  464. /// <returns>int</returns>
  465. public Task<int> FillAsync(DataSet dataSet, int startRecord, int maxRecords, string srcTable)
  466. {
  467. return FillAsync(dataSet, startRecord, maxRecords, srcTable, CancellationToken.None);
  468. }
  469. public Task<int> FillAsync(DataSet dataSet, int startRecord, int maxRecords, string srcTable, CancellationToken cancellationToken)
  470. {
  471. var result = new TaskCompletionSource<int>();
  472. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  473. {
  474. try
  475. {
  476. var fillResult = base.Fill(dataSet, startRecord, maxRecords, srcTable);
  477. result.SetResult(fillResult);
  478. }
  479. catch (Exception ex)
  480. {
  481. result.SetException(ex);
  482. }
  483. }
  484. else
  485. {
  486. result.SetCanceled();
  487. }
  488. return result.Task;
  489. }
  490. /// <summary>
  491. /// Async version of Fill
  492. /// </summary>
  493. /// <param name="dataSet">DataSet to use</param>
  494. /// <param name="srcTable">Source table</param>
  495. /// <param name="dataReader">DataReader to use</param>
  496. /// <param name="startRecord">Start record</param>
  497. /// <param name="maxRecords">Max records</param>
  498. /// <returns></returns>
  499. public Task<int> FillAsync(DataSet dataSet, string srcTable, IDataReader dataReader, int startRecord, int maxRecords)
  500. {
  501. return FillAsync(dataSet, srcTable, dataReader, startRecord, maxRecords, CancellationToken.None);
  502. }
  503. public Task<int> FillAsync(DataSet dataSet, string srcTable, IDataReader dataReader, int startRecord, int maxRecords, CancellationToken cancellationToken)
  504. {
  505. var result = new TaskCompletionSource<int>();
  506. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  507. {
  508. try
  509. {
  510. var fillResult = base.Fill(dataSet, srcTable, dataReader, startRecord, maxRecords);
  511. result.SetResult(fillResult);
  512. }
  513. catch (Exception ex)
  514. {
  515. result.SetException(ex);
  516. }
  517. }
  518. else
  519. {
  520. result.SetCanceled();
  521. }
  522. return result.Task;
  523. }
  524. /// <summary>
  525. /// Async version of Fill
  526. /// </summary>
  527. /// <param name="dataTables">DataTable[] to use</param>
  528. /// <param name="startRecord">Start record</param>
  529. /// <param name="maxRecords">Max records</param>
  530. /// <param name="command">DbCommand to use</param>
  531. /// <param name="behavior">Command Behavior</param>
  532. /// <returns></returns>
  533. public Task<int> FillAsync(DataTable[] dataTables, int startRecord, int maxRecords, IDbCommand command, CommandBehavior behavior)
  534. {
  535. return FillAsync(dataTables, startRecord, maxRecords, command, behavior, CancellationToken.None);
  536. }
  537. public Task<int> FillAsync(DataTable[] dataTables, int startRecord, int maxRecords, IDbCommand command, CommandBehavior behavior, CancellationToken cancellationToken)
  538. {
  539. var result = new TaskCompletionSource<int>();
  540. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  541. {
  542. try
  543. {
  544. var fillResult = base.Fill(dataTables, startRecord, maxRecords, command, behavior);
  545. result.SetResult(fillResult);
  546. }
  547. catch (Exception ex)
  548. {
  549. result.SetException(ex);
  550. }
  551. }
  552. else
  553. {
  554. result.SetCanceled();
  555. }
  556. return result.Task;
  557. }
  558. /// <summary>
  559. /// Async version of Fill
  560. /// </summary>
  561. /// <param name="dataSet">DataSet to use</param>
  562. /// <param name="startRecord">Start record</param>
  563. /// <param name="maxRecords">Max records</param>
  564. /// <param name="srcTable">Source table</param>
  565. /// <param name="command">DbCommand to use</param>
  566. /// <param name="behavior">Command Behavior</param>
  567. /// <returns></returns>
  568. public Task<int> FillAsync(DataSet dataSet, int startRecord, int maxRecords, string srcTable, IDbCommand command, CommandBehavior behavior)
  569. {
  570. return FillAsync(dataSet, startRecord, maxRecords, srcTable, command, behavior, CancellationToken.None);
  571. }
  572. public Task<int> FillAsync(DataSet dataSet, int startRecord, int maxRecords, string srcTable, IDbCommand command, CommandBehavior behavior, CancellationToken cancellationToken)
  573. {
  574. var result = new TaskCompletionSource<int>();
  575. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  576. {
  577. try
  578. {
  579. var fillResult = base.Fill(dataSet, startRecord, maxRecords, srcTable, command, behavior);
  580. result.SetResult(fillResult);
  581. }
  582. catch (Exception ex)
  583. {
  584. result.SetException(ex);
  585. }
  586. }
  587. else
  588. {
  589. result.SetCanceled();
  590. }
  591. return result.Task;
  592. }
  593. #endregion
  594. #region FillSchema
  595. /// <summary>
  596. /// Async version of FillSchema
  597. /// </summary>
  598. /// <param name="dataSet">DataSet to use</param>
  599. /// <param name="schemaType">Schema Type</param>
  600. /// <returns>DataTable[]</returns>
  601. public Task<DataTable[]> FillSchemaAsync(DataSet dataSet, SchemaType schemaType)
  602. {
  603. return FillSchemaAsync(dataSet, schemaType, CancellationToken.None);
  604. }
  605. public Task<DataTable[]> FillSchemaAsync(DataSet dataSet, SchemaType schemaType, CancellationToken cancellationToken)
  606. {
  607. var result = new TaskCompletionSource<DataTable[]>();
  608. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  609. {
  610. try
  611. {
  612. var schemaResult = base.FillSchema(dataSet, schemaType);
  613. result.SetResult(schemaResult);
  614. }
  615. catch (Exception ex)
  616. {
  617. result.SetException(ex);
  618. }
  619. }
  620. else
  621. {
  622. result.SetCanceled();
  623. }
  624. return result.Task;
  625. }
  626. /// <summary>
  627. /// Async version of FillSchema
  628. /// </summary>
  629. /// <param name="dataSet">DataSet to use</param>
  630. /// <param name="schemaType">Schema Type</param>
  631. /// <param name="srcTable">Source Table</param>
  632. /// <returns>DataTable[]</returns>
  633. public Task<DataTable[]> FillSchemaAsync(DataSet dataSet, SchemaType schemaType, string srcTable)
  634. {
  635. return FillSchemaAsync(dataSet, schemaType, srcTable, CancellationToken.None);
  636. }
  637. public Task<DataTable[]> FillSchemaAsync(DataSet dataSet, SchemaType schemaType, string srcTable, CancellationToken cancellationToken)
  638. {
  639. var result = new TaskCompletionSource<DataTable[]>();
  640. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  641. {
  642. try
  643. {
  644. var schemaResult = base.FillSchema(dataSet, schemaType, srcTable);
  645. result.SetResult(schemaResult);
  646. }
  647. catch (Exception ex)
  648. {
  649. result.SetException(ex);
  650. }
  651. }
  652. else
  653. {
  654. result.SetCanceled();
  655. }
  656. return result.Task;
  657. }
  658. /// <summary>
  659. /// Async version of FillSchema
  660. /// </summary>
  661. /// <param name="dataSet">DataSet to use</param>
  662. /// <param name="schemaType">Schema Type</param>
  663. /// <param name="srcTable">Source Table</param>
  664. /// <param name="dataReader">DataReader to use</param>
  665. /// <returns>DataTable[]</returns>
  666. public Task<DataTable[]> FillSchemaAsync(DataSet dataSet, SchemaType schemaType, string srcTable, IDataReader dataReader)
  667. {
  668. return FillSchemaAsync(dataSet, schemaType, srcTable, dataReader, CancellationToken.None);
  669. }
  670. public Task<DataTable[]> FillSchemaAsync(DataSet dataSet, SchemaType schemaType, string srcTable, IDataReader dataReader, CancellationToken cancellationToken)
  671. {
  672. var result = new TaskCompletionSource<DataTable[]>();
  673. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  674. {
  675. try
  676. {
  677. var schemaResult = base.FillSchema(dataSet, schemaType, srcTable, dataReader);
  678. result.SetResult(schemaResult);
  679. }
  680. catch (Exception ex)
  681. {
  682. result.SetException(ex);
  683. }
  684. }
  685. else
  686. {
  687. result.SetCanceled();
  688. }
  689. return result.Task;
  690. }
  691. /// <summary>
  692. /// Async version of FillSchema
  693. /// </summary>
  694. /// <param name="dataSet">DataSet to use</param>
  695. /// <param name="schemaType">Schema Type</param>
  696. /// <param name="command">DBCommand to use</param>
  697. /// <param name="srcTable">Source Table</param>
  698. /// <param name="behavior">Command Behavior</param>
  699. /// <returns>DataTable[]</returns>
  700. public Task<DataTable[]> FillSchemaAsync(DataSet dataSet, SchemaType schemaType, IDbCommand command, string srcTable, CommandBehavior behavior)
  701. {
  702. return FillSchemaAsync(dataSet, schemaType, command, srcTable, behavior, CancellationToken.None);
  703. }
  704. public Task<DataTable[]> FillSchemaAsync(DataSet dataSet, SchemaType schemaType, IDbCommand command, string srcTable, CommandBehavior behavior, CancellationToken cancellationToken)
  705. {
  706. var result = new TaskCompletionSource<DataTable[]>();
  707. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  708. {
  709. try
  710. {
  711. var schemaResult = base.FillSchema(dataSet, schemaType, command, srcTable, behavior);
  712. result.SetResult(schemaResult);
  713. }
  714. catch (Exception ex)
  715. {
  716. result.SetException(ex);
  717. }
  718. }
  719. else
  720. {
  721. result.SetCanceled();
  722. }
  723. return result.Task;
  724. }
  725. /// <summary>
  726. /// Async version of FillSchema
  727. /// </summary>
  728. /// <param name="dataTable">DataTable to use</param>
  729. /// <param name="schemaType">Schema Type</param>
  730. /// <returns>DataTable</returns>
  731. public Task<DataTable> FillSchemaAsync(DataTable dataTable, SchemaType schemaType)
  732. {
  733. return FillSchemaAsync(dataTable, schemaType, CancellationToken.None);
  734. }
  735. public Task<DataTable> FillSchemaAsync(DataTable dataTable, SchemaType schemaType, CancellationToken cancellationToken)
  736. {
  737. var result = new TaskCompletionSource<DataTable>();
  738. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  739. {
  740. try
  741. {
  742. var schemaResult = base.FillSchema(dataTable, schemaType);
  743. result.SetResult(schemaResult);
  744. }
  745. catch (Exception ex)
  746. {
  747. result.SetException(ex);
  748. }
  749. }
  750. else
  751. {
  752. result.SetCanceled();
  753. }
  754. return result.Task;
  755. }
  756. /// <summary>
  757. /// Async version of FillSchema
  758. /// </summary>
  759. /// <param name="dataTable">DataTable to use</param>
  760. /// <param name="schemaType">Schema Type</param>
  761. /// <param name="dataReader">DataReader to use</param>
  762. /// <returns>DataTable</returns>
  763. public Task<DataTable> FillSchemaAsync(DataTable dataTable, SchemaType schemaType, IDataReader dataReader)
  764. {
  765. return FillSchemaAsync(dataTable, schemaType, dataReader, CancellationToken.None);
  766. }
  767. public Task<DataTable> FillSchemaAsync(DataTable dataTable, SchemaType schemaType, IDataReader dataReader, CancellationToken cancellationToken)
  768. {
  769. var result = new TaskCompletionSource<DataTable>();
  770. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  771. {
  772. try
  773. {
  774. var schemaResult = base.FillSchema(dataTable, schemaType, dataReader);
  775. result.SetResult(schemaResult);
  776. }
  777. catch (Exception ex)
  778. {
  779. result.SetException(ex);
  780. }
  781. }
  782. else
  783. {
  784. result.SetCanceled();
  785. }
  786. return result.Task;
  787. }
  788. /// <summary>
  789. /// Async version of FillSchema
  790. /// </summary>
  791. /// <param name="dataTable">DataTable to use</param>
  792. /// <param name="schemaType">Schema Type</param>
  793. /// <param name="command">DBCommand to use</param>
  794. /// <param name="behavior">Command Behavior</param>
  795. /// <returns>DataTable</returns>
  796. public Task<DataTable> FillSchemaAsync(DataTable dataTable, SchemaType schemaType, IDbCommand command, CommandBehavior behavior)
  797. {
  798. return FillSchemaAsync(dataTable, schemaType, command, behavior, CancellationToken.None);
  799. }
  800. public Task<DataTable> FillSchemaAsync(DataTable dataTable, SchemaType schemaType, IDbCommand command, CommandBehavior behavior, CancellationToken cancellationToken)
  801. {
  802. var result = new TaskCompletionSource<DataTable>();
  803. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  804. {
  805. try
  806. {
  807. var schemaResult = base.FillSchema(dataTable, schemaType, command, behavior);
  808. result.SetResult(schemaResult);
  809. }
  810. catch (Exception ex)
  811. {
  812. result.SetException(ex);
  813. }
  814. }
  815. else
  816. {
  817. result.SetCanceled();
  818. }
  819. return result.Task;
  820. }
  821. #endregion
  822. #region Update
  823. /// <summary>
  824. /// Async version of Update
  825. /// </summary>
  826. /// <param name="dataRows">DataRow[] to use</param>
  827. /// <returns>int</returns>
  828. public Task<int> UpdateAsync(DataRow[] dataRows)
  829. {
  830. return UpdateAsync(dataRows, CancellationToken.None);
  831. }
  832. public Task<int> UpdateAsync(DataRow[] dataRows, CancellationToken cancellationToken)
  833. {
  834. var result = new TaskCompletionSource<int>();
  835. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  836. {
  837. try
  838. {
  839. var update = base.Update(dataRows);
  840. result.SetResult(update);
  841. }
  842. catch (Exception ex)
  843. {
  844. result.SetException(ex);
  845. }
  846. }
  847. else
  848. {
  849. result.SetCanceled();
  850. }
  851. return result.Task;
  852. }
  853. /// <summary>
  854. /// Async version of Update
  855. /// </summary>
  856. /// <param name="dataSet">DataSet to use</param>
  857. /// <returns>int</returns>
  858. public Task<int> UpdateAsync(DataSet dataSet)
  859. {
  860. return UpdateAsync(dataSet, CancellationToken.None);
  861. }
  862. public Task<int> UpdateAsync(DataSet dataSet, CancellationToken cancellationToken)
  863. {
  864. var result = new TaskCompletionSource<int>();
  865. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  866. {
  867. try
  868. {
  869. var update = base.Update(dataSet);
  870. result.SetResult(update);
  871. }
  872. catch (Exception ex)
  873. {
  874. result.SetException(ex);
  875. }
  876. }
  877. else
  878. {
  879. result.SetCanceled();
  880. }
  881. return result.Task;
  882. }
  883. /// <summary>
  884. /// Async version of Update
  885. /// </summary>
  886. /// <param name="dataTable">DataTable to use</param>
  887. /// <returns>int</returns>
  888. public Task<int> UpdateAsync(DataTable dataTable)
  889. {
  890. return UpdateAsync(dataTable, CancellationToken.None);
  891. }
  892. public Task<int> UpdateAsync(DataTable dataTable, CancellationToken cancellationToken)
  893. {
  894. var result = new TaskCompletionSource<int>();
  895. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  896. {
  897. try
  898. {
  899. var update = base.Update(dataTable);
  900. result.SetResult(update);
  901. }
  902. catch (Exception ex)
  903. {
  904. result.SetException(ex);
  905. }
  906. }
  907. else
  908. {
  909. result.SetCanceled();
  910. }
  911. return result.Task;
  912. }
  913. /// <summary>
  914. /// Async version of Update
  915. /// </summary>
  916. /// <param name="dataRows">DataRow[] to use</param>
  917. /// <param name="tableMapping">Data Table Mapping</param>
  918. /// <returns>int</returns>
  919. public Task<int> UpdateAsync(DataRow[] dataRows, DataTableMapping tableMapping)
  920. {
  921. return UpdateAsync(dataRows, tableMapping, CancellationToken.None);
  922. }
  923. public Task<int> UpdateAsync(DataRow[] dataRows, DataTableMapping tableMapping, CancellationToken cancellationToken)
  924. {
  925. var result = new TaskCompletionSource<int>();
  926. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  927. {
  928. try
  929. {
  930. var update = base.Update(dataRows, tableMapping);
  931. result.SetResult(update);
  932. }
  933. catch (Exception ex)
  934. {
  935. result.SetException(ex);
  936. }
  937. }
  938. else
  939. {
  940. result.SetCanceled();
  941. }
  942. return result.Task;
  943. }
  944. /// <summary>
  945. /// Async version of Update
  946. /// </summary>
  947. /// <param name="dataSet">DataSet to use</param>
  948. /// <param name="srcTable">Source Table</param>
  949. /// <returns></returns>
  950. public Task<int> UpdateAsync(DataSet dataSet, string srcTable)
  951. {
  952. return UpdateAsync(dataSet, srcTable, CancellationToken.None);
  953. }
  954. public Task<int> UpdateAsync(DataSet dataSet, string srcTable, CancellationToken cancellationToken)
  955. {
  956. var result = new TaskCompletionSource<int>();
  957. if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested)
  958. {
  959. try
  960. {
  961. var update = base.Update(dataSet, srcTable);
  962. result.SetResult(update);
  963. }
  964. catch (Exception ex)
  965. {
  966. result.SetException(ex);
  967. }
  968. }
  969. else
  970. {
  971. result.SetCanceled();
  972. }
  973. return result.Task;
  974. }
  975. #endregion
  976. #endregion
  977. #endif
  978. }
  979. /// <summary>
  980. /// Represents the method that will handle the <see cref="MySqlDataAdapter.RowUpdating"/> event of a <see cref="MySqlDataAdapter"/>.
  981. /// </summary>
  982. internal delegate void MySqlRowUpdatingEventHandler(object sender, MySqlRowUpdatingEventArgs e);
  983. /// <summary>
  984. /// Represents the method that will handle the <see cref="MySqlDataAdapter.RowUpdated"/> event of a <see cref="MySqlDataAdapter"/>.
  985. /// </summary>
  986. internal delegate void MySqlRowUpdatedEventHandler(object sender, MySqlRowUpdatedEventArgs e);
  987. /// <summary>
  988. /// Provides data for the RowUpdating event. This class cannot be inherited.
  989. /// </summary>
  990. internal sealed class MySqlRowUpdatingEventArgs : RowUpdatingEventArgs
  991. {
  992. /// <summary>
  993. /// Initializes a new instance of the MySqlRowUpdatingEventArgs class.
  994. /// </summary>
  995. /// <param name="row">The <see cref="DataRow"/> to
  996. /// <see cref="DbDataAdapter.Update(DataSet)"/>.</param>
  997. /// <param name="command">The <see cref="IDbCommand"/> to execute during <see cref="DbDataAdapter.Update(DataSet)"/>.</param>
  998. /// <param name="statementType">One of the <see cref="StatementType"/> values that specifies the type of query executed.</param>
  999. /// <param name="tableMapping">The <see cref="DataTableMapping"/> sent through an <see cref="DbDataAdapter.Update(DataSet)"/>.</param>
  1000. public MySqlRowUpdatingEventArgs(DataRow row, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
  1001. : base(row, command, statementType, tableMapping)
  1002. {
  1003. }
  1004. /// <summary>
  1005. /// Gets or sets the MySqlCommand to execute when performing the Update.
  1006. /// </summary>
  1007. new public MySqlCommand Command
  1008. {
  1009. get { return (MySqlCommand)base.Command; }
  1010. set { base.Command = value; }
  1011. }
  1012. }
  1013. /// <summary>
  1014. /// Provides data for the RowUpdated event. This class cannot be inherited.
  1015. /// </summary>
  1016. internal sealed class MySqlRowUpdatedEventArgs : RowUpdatedEventArgs
  1017. {
  1018. /// <summary>
  1019. /// Initializes a new instance of the MySqlRowUpdatedEventArgs class.
  1020. /// </summary>
  1021. /// <param name="row">The <see cref="DataRow"/> sent through an <see cref="DbDataAdapter.Update(DataSet)"/>.</param>
  1022. /// <param name="command">The <see cref="IDbCommand"/> executed when <see cref="DbDataAdapter.Update(DataSet)"/> is called.</param>
  1023. /// <param name="statementType">One of the <see cref="StatementType"/> values that specifies the type of query executed.</param>
  1024. /// <param name="tableMapping">The <see cref="DataTableMapping"/> sent through an <see cref="DbDataAdapter.Update(DataSet)"/>.</param>
  1025. public MySqlRowUpdatedEventArgs(DataRow row, IDbCommand command, StatementType statementType, DataTableMapping tableMapping)
  1026. : base(row, command, statementType, tableMapping)
  1027. {
  1028. }
  1029. /// <summary>
  1030. /// Gets or sets the MySqlCommand executed when Update is called.
  1031. /// </summary>
  1032. new public MySqlCommand Command
  1033. {
  1034. get { return (MySqlCommand)base.Command; }
  1035. }
  1036. }
  1037. }
  1038. #endif