// Copyright ?2004, 2018, Oracle and/or its affiliates. All rights reserved. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License, version 2.0, as // published by the Free Software Foundation. // // This program is also distributed with certain software (including // but not limited to OpenSSL) that is licensed under separate terms, // as designated in a particular file or component or in included license // documentation. The authors of MySQL hereby grant you an // additional permission to link the program and your derivative works // with the separately licensed software that they have included with // MySQL. // // Without limiting anything contained in the foregoing, this file, // which is part of MySQL Connector/NET, is also subject to the // Universal FOSS Exception, version 1.0, a copy of which can be found at // http://oss.oracle.com/licenses/universal-foss-exception. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License, version 2.0, for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA using System; using System.Data; using System.Data.Common; using System.ComponentModel; using System.Collections.Generic; using System.Threading.Tasks; using System.Threading; using System.Drawing; namespace MySql.Data.MySqlClient { /// #if NET452 [ToolboxBitmap(typeof(MySqlDataAdapter), "MySqlClient.resources.dataadapter.bmp")] #endif [DesignerCategory("Code")] [Designer("MySql.Data.MySqlClient.Design.MySqlDataAdapterDesigner,MySqlClient.Design")] public sealed class MySqlDataAdapter : DbDataAdapter, IDbDataAdapter, IDataAdapter { private bool loadingDefaults; private int updateBatchSize; List commandBatch; /// /// Occurs during Update before a command is executed against the data source. The attempt to update is made, so the event fires. /// public event MySqlRowUpdatingEventHandler RowUpdating; /// /// Occurs during Update after a command is executed against the data source. The attempt to update is made, so the event fires. /// public event MySqlRowUpdatedEventHandler RowUpdated; /// public MySqlDataAdapter() { this.loadingDefaults = true; this.updateBatchSize = 1; } /// public MySqlDataAdapter(MySqlCommand selectCommand) : this() { this.SelectCommand = selectCommand; } /// public MySqlDataAdapter(string selectCommandText, MySqlConnection connection) : this() { this.SelectCommand = new MySqlCommand(selectCommandText, connection); } /// public MySqlDataAdapter(string selectCommandText, string selectConnString) : this() { this.SelectCommand = new MySqlCommand( selectCommandText, new MySqlConnection(selectConnString)); } #region Properties /// [Description("Used during Update for deleted rows in Dataset.")] public new MySqlCommand DeleteCommand { get { return (MySqlCommand)base.DeleteCommand; } set { base.DeleteCommand = value; } } /// [Description("Used during Update for new rows in Dataset.")] public new MySqlCommand InsertCommand { get { return (MySqlCommand)base.InsertCommand; } set { base.InsertCommand = value; } } /// [Description("Used during Fill/FillSchema")] [Category("Fill")] public new MySqlCommand SelectCommand { get { return (MySqlCommand)base.SelectCommand; } set { base.SelectCommand = value; } } /// [Description("Used during Update for modified rows in Dataset.")] public new MySqlCommand UpdateCommand { get { return (MySqlCommand)base.UpdateCommand; } set { base.UpdateCommand = value; } } internal bool LoadDefaults { get { return this.loadingDefaults; } set { this.loadingDefaults = value; } } #endregion /// /// Open connection if it was closed. /// Necessary to workaround "connection must be open and valid" error /// with batched updates. /// /// Row state /// list of opened connections /// If connection is opened by this function, the list is updated /// /// true if connection was opened private void OpenConnectionIfClosed( DataRowState state, List openedConnections) { MySqlCommand cmd = null; switch (state) { case DataRowState.Added: cmd = this.InsertCommand; break; case DataRowState.Deleted: cmd = this.DeleteCommand; break; case DataRowState.Modified: cmd = this.UpdateCommand; break; default: return; } if (cmd != null && cmd.Connection != null && cmd.Connection.connectionState == ConnectionState.Closed) { cmd.Connection.Open(); openedConnections.Add(cmd.Connection); } } protected override int Update(DataRow[] dataRows, DataTableMapping tableMapping) { List connectionsOpened = new List(); try { // Open connections for insert/update/update commands, if // connections are closed. foreach (DataRow row in dataRows) { this.OpenConnectionIfClosed(row.RowState, connectionsOpened); } int ret = base.Update(dataRows, tableMapping); return ret; } finally { foreach (MySqlConnection c in connectionsOpened) { c.Close(); } } } #region Batching Support public override int UpdateBatchSize { get { return this.updateBatchSize; } set { this.updateBatchSize = value; } } protected override void InitializeBatching() { this.commandBatch = new List(); } protected override int AddToBatch(IDbCommand command) { // the first time each command is asked to be batched, we ask // that command to prepare its batchable command text. We only want // to do this one time for each command MySqlCommand commandToBatch = (MySqlCommand)command; if (commandToBatch.BatchableCommandText == null) { commandToBatch.GetCommandTextForBatching(); } IDbCommand cloneCommand = (IDbCommand)((ICloneable)command).Clone(); this.commandBatch.Add(cloneCommand); return this.commandBatch.Count - 1; } protected override int ExecuteBatch() { int recordsAffected = 0; int index = 0; while (index < this.commandBatch.Count) { MySqlCommand cmd = (MySqlCommand)this.commandBatch[index++]; for (int index2 = index; index2 < this.commandBatch.Count; index2++, index++) { MySqlCommand cmd2 = (MySqlCommand)this.commandBatch[index2]; if (cmd2.BatchableCommandText == null || cmd2.CommandText != cmd.CommandText) { break; } cmd.AddToBatch(cmd2); } recordsAffected += cmd.ExecuteNonQuery(); } return recordsAffected; } protected override void ClearBatch() { if (this.commandBatch.Count > 0) { MySqlCommand cmd = (MySqlCommand)this.commandBatch[0]; if (cmd.Batch != null) { cmd.Batch.Clear(); } } this.commandBatch.Clear(); } protected override void TerminateBatching() { this.ClearBatch(); this.commandBatch = null; } protected override IDataParameter GetBatchedParameter(int commandIdentifier, int parameterIndex) { return (IDataParameter)this.commandBatch[commandIdentifier].Parameters[parameterIndex]; } #endregion /// /// Overridden. See . /// /// /// /// /// /// override protected RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) { return new MySqlRowUpdatedEventArgs(dataRow, command, statementType, tableMapping); } /// /// Overridden. See . /// /// /// /// /// /// override protected RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) { return new MySqlRowUpdatingEventArgs(dataRow, command, statementType, tableMapping); } /// /// Overridden. Raises the RowUpdating event. /// /// A MySqlRowUpdatingEventArgs that contains the event data. override protected void OnRowUpdating(RowUpdatingEventArgs value) { if (this.RowUpdating != null) { this.RowUpdating(this, (value as MySqlRowUpdatingEventArgs)); } } /// /// Overridden. Raises the RowUpdated event. /// /// A MySqlRowUpdatedEventArgs that contains the event data. override protected void OnRowUpdated(RowUpdatedEventArgs value) { if (this.RowUpdated != null) { this.RowUpdated(this, (value as MySqlRowUpdatedEventArgs)); } } #region Async #region Fill /// /// Asynchronous version of the Fill method. /// /// The to fill records with. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataSet dataSet) { return this.FillAsync(dataSet, CancellationToken.None); } /// /// Asynchronous version of the Fill method. /// /// The to fill records with. /// The cancellation token. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataSet dataSet, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var fillResult = base.Fill(dataSet); result.SetResult(fillResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Asynchronous version of the Fill method. /// /// The name of the to use for table mapping. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataTable dataTable) { return this.FillAsync(dataTable, CancellationToken.None); } /// /// Asynchronous version of the Fill method. /// /// The name of the to use for table mapping. /// The cancellation token. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataTable dataTable, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var fillResult = base.Fill(dataTable); result.SetResult(fillResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// The name of the source table to use for table mapping. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataSet dataSet, string srcTable) { return this.FillAsync(dataSet, srcTable, CancellationToken.None); } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// The name of the source table to use for table mapping. /// The cancellation token. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataSet dataSet, string srcTable, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var fillResult = base.Fill(dataSet, srcTable); result.SetResult(fillResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// An instance of . /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataTable dataTable, IDataReader dataReader) { return this.FillAsync(dataTable, dataReader, CancellationToken.None); } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// An instance of . /// The cancellation token. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataTable dataTable, IDataReader dataReader, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var fillResult = base.Fill(dataTable, dataReader); result.SetResult(fillResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// The SQL SELECT statement used to retrieve rows from the data source. /// One of the values. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataTable dataTable, IDbCommand command, CommandBehavior behavior) { return this.FillAsync(dataTable, command, behavior, CancellationToken.None); } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// The SQL SELECT statement used to retrieve rows from the data source. /// One of the values. /// The cancellation token. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataTable dataTable, IDbCommand command, CommandBehavior behavior, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var fillResult = base.Fill(dataTable, command, behavior); result.SetResult(fillResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Asynchronous version of the Fill method. /// /// The start record. /// The max number of affected records. /// The s to fill with records. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(int startRecord, int maxRecords, params DataTable[] dataTables) { return this.FillAsync(startRecord, maxRecords, CancellationToken.None, dataTables); } /// /// Asynchronous version of the Fill method. /// /// The start record. /// The max number of affected records. /// The cancellation token. /// The s to fill with records. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(int startRecord, int maxRecords, CancellationToken cancellationToken, params DataTable[] dataTables) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var fillResult = base.Fill(startRecord, maxRecords, dataTables); result.SetResult(fillResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// The start record. /// The max number of affected records. /// The name of the source table to use for table mapping. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataSet dataSet, int startRecord, int maxRecords, string srcTable) { return this.FillAsync(dataSet, startRecord, maxRecords, srcTable, CancellationToken.None); } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// The start record. /// The max number of affected records. /// The name of the source table to use for table mapping. /// The cancellation token. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataSet dataSet, int startRecord, int maxRecords, string srcTable, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var fillResult = base.Fill(dataSet, startRecord, maxRecords, srcTable); result.SetResult(fillResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// The name of the source table to use for table mapping. /// An instance of . /// The start record. /// The max number of affected records. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataSet dataSet, string srcTable, IDataReader dataReader, int startRecord, int maxRecords) { return this.FillAsync(dataSet, srcTable, dataReader, startRecord, maxRecords, CancellationToken.None); } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// The name of the source table to use for table mapping. /// An instance of . /// The start record. /// The max number of affected records. /// The cancellation token. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataSet dataSet, string srcTable, IDataReader dataReader, int startRecord, int maxRecords, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var fillResult = base.Fill(dataSet, srcTable, dataReader, startRecord, maxRecords); result.SetResult(fillResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Asynchronous version of the Fill method. /// /// The s to fill with records. /// The start record. /// The max number of affected records. /// The SQL SELECT statement used to retrieve rows from the data source. /// One of the values. /// The number of rows successfully added to or refreshed in the s. public Task FillAsync(DataTable[] dataTables, int startRecord, int maxRecords, IDbCommand command, CommandBehavior behavior) { return this.FillAsync(dataTables, startRecord, maxRecords, command, behavior, CancellationToken.None); } /// /// Asynchronous version of the Fill method. /// /// The s to fill with records. /// The start record. /// The max number of affected records. /// The SQL SELECT statement used to retrieve rows from the data source. /// One of the values. /// The cancellation token. /// The number of rows successfully added to or refreshed in the s. public Task FillAsync(DataTable[] dataTables, int startRecord, int maxRecords, IDbCommand command, CommandBehavior behavior, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var fillResult = base.Fill(dataTables, startRecord, maxRecords, command, behavior); result.SetResult(fillResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// The start record. /// The max number of affected records. /// The name of the source table to use for table mapping. /// The SQL SELECT statement used to retrieve rows from the data source. /// One of the values. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataSet dataSet, int startRecord, int maxRecords, string srcTable, IDbCommand command, CommandBehavior behavior) { return this.FillAsync(dataSet, startRecord, maxRecords, srcTable, command, behavior, CancellationToken.None); } /// /// Asynchronous version of the Fill method. /// /// The to fill with records. /// The start record. /// The max number of affected records. /// The name of the source table to use for table mapping. /// The SQL SELECT statement used to retrieve rows from the data source. /// One of the values. /// The cancellation token. /// The number of rows successfully added to or refreshed in the . public Task FillAsync(DataSet dataSet, int startRecord, int maxRecords, string srcTable, IDbCommand command, CommandBehavior behavior, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var fillResult = base.Fill(dataSet, startRecord, maxRecords, srcTable, command, behavior); result.SetResult(fillResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } #endregion #region FillSchema /// /// Async version of FillSchema /// /// DataSet to use /// Schema Type /// DataTable[] public Task FillSchemaAsync(DataSet dataSet, SchemaType schemaType) { return this.FillSchemaAsync(dataSet, schemaType, CancellationToken.None); } public Task FillSchemaAsync(DataSet dataSet, SchemaType schemaType, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var schemaResult = base.FillSchema(dataSet, schemaType); result.SetResult(schemaResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Async version of FillSchema /// /// DataSet to use /// Schema Type /// Source Table /// DataTable[] public Task FillSchemaAsync(DataSet dataSet, SchemaType schemaType, string srcTable) { return this.FillSchemaAsync(dataSet, schemaType, srcTable, CancellationToken.None); } public Task FillSchemaAsync(DataSet dataSet, SchemaType schemaType, string srcTable, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var schemaResult = base.FillSchema(dataSet, schemaType, srcTable); result.SetResult(schemaResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Async version of FillSchema /// /// DataSet to use /// Schema Type /// Source Table /// DataReader to use /// DataTable[] public Task FillSchemaAsync(DataSet dataSet, SchemaType schemaType, string srcTable, IDataReader dataReader) { return this.FillSchemaAsync(dataSet, schemaType, srcTable, dataReader, CancellationToken.None); } public Task FillSchemaAsync(DataSet dataSet, SchemaType schemaType, string srcTable, IDataReader dataReader, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var schemaResult = base.FillSchema(dataSet, schemaType, srcTable, dataReader); result.SetResult(schemaResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Async version of FillSchema /// /// DataSet to use /// Schema Type /// DBCommand to use /// Source Table /// Command Behavior /// DataTable[] public Task FillSchemaAsync(DataSet dataSet, SchemaType schemaType, IDbCommand command, string srcTable, CommandBehavior behavior) { return this.FillSchemaAsync(dataSet, schemaType, command, srcTable, behavior, CancellationToken.None); } public Task FillSchemaAsync(DataSet dataSet, SchemaType schemaType, IDbCommand command, string srcTable, CommandBehavior behavior, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var schemaResult = base.FillSchema(dataSet, schemaType, command, srcTable, behavior); result.SetResult(schemaResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Async version of FillSchema /// /// DataTable to use /// Schema Type /// DataTable public Task FillSchemaAsync(DataTable dataTable, SchemaType schemaType) { return this.FillSchemaAsync(dataTable, schemaType, CancellationToken.None); } public Task FillSchemaAsync(DataTable dataTable, SchemaType schemaType, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var schemaResult = base.FillSchema(dataTable, schemaType); result.SetResult(schemaResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Async version of FillSchema /// /// DataTable to use /// Schema Type /// DataReader to use /// DataTable public Task FillSchemaAsync(DataTable dataTable, SchemaType schemaType, IDataReader dataReader) { return this.FillSchemaAsync(dataTable, schemaType, dataReader, CancellationToken.None); } public Task FillSchemaAsync(DataTable dataTable, SchemaType schemaType, IDataReader dataReader, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var schemaResult = base.FillSchema(dataTable, schemaType, dataReader); result.SetResult(schemaResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Async version of FillSchema /// /// DataTable to use /// Schema Type /// DBCommand to use /// Command Behavior /// DataTable public Task FillSchemaAsync(DataTable dataTable, SchemaType schemaType, IDbCommand command, CommandBehavior behavior) { return this.FillSchemaAsync(dataTable, schemaType, command, behavior, CancellationToken.None); } public Task FillSchemaAsync(DataTable dataTable, SchemaType schemaType, IDbCommand command, CommandBehavior behavior, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var schemaResult = base.FillSchema(dataTable, schemaType, command, behavior); result.SetResult(schemaResult); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } #endregion #region Update /// /// Async version of Update /// /// DataRow[] to use /// int public Task UpdateAsync(DataRow[] dataRows) { return this.UpdateAsync(dataRows, CancellationToken.None); } public Task UpdateAsync(DataRow[] dataRows, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var update = base.Update(dataRows); result.SetResult(update); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Async version of Update /// /// DataSet to use /// int public Task UpdateAsync(DataSet dataSet) { return this.UpdateAsync(dataSet, CancellationToken.None); } public Task UpdateAsync(DataSet dataSet, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var update = base.Update(dataSet); result.SetResult(update); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Async version of Update /// /// DataTable to use /// int public Task UpdateAsync(DataTable dataTable) { return this.UpdateAsync(dataTable, CancellationToken.None); } public Task UpdateAsync(DataTable dataTable, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var update = base.Update(dataTable); result.SetResult(update); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Async version of Update /// /// DataRow[] to use /// Data Table Mapping /// int public Task UpdateAsync(DataRow[] dataRows, DataTableMapping tableMapping) { return this.UpdateAsync(dataRows, tableMapping, CancellationToken.None); } public Task UpdateAsync(DataRow[] dataRows, DataTableMapping tableMapping, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var update = base.Update(dataRows, tableMapping); result.SetResult(update); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } /// /// Async version of Update /// /// DataSet to use /// Source Table /// public Task UpdateAsync(DataSet dataSet, string srcTable) { return this.UpdateAsync(dataSet, srcTable, CancellationToken.None); } public Task UpdateAsync(DataSet dataSet, string srcTable, CancellationToken cancellationToken) { var result = new TaskCompletionSource(); if (cancellationToken == CancellationToken.None || !cancellationToken.IsCancellationRequested) { try { var update = base.Update(dataSet, srcTable); result.SetResult(update); } catch (Exception ex) { result.SetException(ex); } } else { result.SetCanceled(); } return result.Task; } #endregion #endregion } /// /// Represents the method that will handle the event of a . /// public delegate void MySqlRowUpdatingEventHandler(object sender, MySqlRowUpdatingEventArgs e); /// /// Represents the method that will handle the event of a . /// public delegate void MySqlRowUpdatedEventHandler(object sender, MySqlRowUpdatedEventArgs e); /// /// Provides data for the RowUpdating event. This class cannot be inherited. /// public sealed class MySqlRowUpdatingEventArgs : RowUpdatingEventArgs { /// /// Initializes a new instance of the MySqlRowUpdatingEventArgs class. /// /// The to /// . /// The to execute during . /// One of the values that specifies the type of query executed. /// The sent through an . public MySqlRowUpdatingEventArgs(DataRow row, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) : base(row, command, statementType, tableMapping) { } /// /// Gets or sets the MySqlCommand to execute when performing the Update. /// new public MySqlCommand Command { get { return (MySqlCommand)base.Command; } set { base.Command = value; } } } /// /// Provides data for the RowUpdated event. This class cannot be inherited. /// public sealed class MySqlRowUpdatedEventArgs : RowUpdatedEventArgs { /// /// Initializes a new instance of the MySqlRowUpdatedEventArgs class. /// /// The sent through an . /// The executed when is called. /// One of the values that specifies the type of query executed. /// The sent through an . public MySqlRowUpdatedEventArgs(DataRow row, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) : base(row, command, statementType, tableMapping) { } /// /// Gets or sets the MySqlCommand executed when Update is called. /// new public MySqlCommand Command { get { return (MySqlCommand)base.Command; } } } }