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.

1125 lines
35 KiB

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