/// <summary> /// Update a metadata row /// </summary> internal async Task <(SyncContext context, bool metadataUpdated)> InternalUpdateMetadatasAsync(IScopeInfo scopeInfo, SyncContext context, DbSyncAdapter syncAdapter, SyncRow row, Guid?senderScopeId, bool forceWrite, DbConnection connection, DbTransaction transaction) { context.SyncStage = SyncStage.ChangesApplying; var(command, _) = await syncAdapter.GetCommandAsync(DbCommandType.UpdateMetadata, connection, transaction); if (command == null) { return(context, false); } // Set the parameters value from row syncAdapter.SetColumnParametersValues(command, row); // Set the special parameters for update syncAdapter.AddScopeParametersValues(command, senderScopeId, 0, row.RowState == DataRowState.Deleted, forceWrite); await this.InterceptAsync(new DbCommandArgs(context, command, connection, transaction)).ConfigureAwait(false); var metadataUpdatedRowsCount = await command.ExecuteNonQueryAsync().ConfigureAwait(false); // Check if we have a return value instead var syncRowCountParam = DbSyncAdapter.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { metadataUpdatedRowsCount = (int)syncRowCountParam.Value; } command.Dispose(); return(context, metadataUpdatedRowsCount > 0); }
/// <summary> /// Apply a single update in the current datasource. if forceWrite, override conflict situation and force the update /// </summary> private async Task <bool> InternalApplyConflictUpdateAsync(SyncContext context, DbSyncAdapter syncAdapter, SyncRow row, long?lastTimestamp, Guid?senderScopeId, bool forceWrite, DbConnection connection, DbTransaction transaction) { if (row.Table == null) { throw new ArgumentException("Schema table is not present in the row"); } var command = await syncAdapter.GetCommandAsync(DbCommandType.UpdateRow, connection, transaction); // Set the parameters value from row syncAdapter.SetColumnParametersValues(command, row); // Set the special parameters for update syncAdapter.AddScopeParametersValues(command, senderScopeId, lastTimestamp, false, forceWrite); var rowUpdatedCount = await command.ExecuteNonQueryAsync().ConfigureAwait(false); // Check if we have a return value instead var syncRowCountParam = DbSyncAdapter.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { rowUpdatedCount = (int)syncRowCountParam.Value; } return(rowUpdatedCount > 0); }
/// <summary> /// Reset a table, deleting rows from table and tracking_table /// </summary> internal async Task <bool> InternalResetTableAsync(SyncContext context, DbSyncAdapter syncAdapter, DbConnection connection, DbTransaction transaction) { var command = await syncAdapter.GetCommandAsync(DbCommandType.Reset, connection, transaction); var rowCount = await command.ExecuteNonQueryAsync().ConfigureAwait(false); return(rowCount > 0); }
/// <summary> /// Try to get a source row /// </summary> private async Task <SyncRow> InternalGetConflictRowAsync(SyncContext context, DbSyncAdapter syncAdapter, Guid localScopeId, SyncRow primaryKeyRow, SyncTable schema, DbConnection connection, DbTransaction transaction) { // Get the row in the local repository var command = await syncAdapter.GetCommandAsync(DbCommandType.SelectRow, connection, transaction); // set the primary keys columns as parameters syncAdapter.SetColumnParametersValues(command, primaryKeyRow); // Create a select table based on the schema in parameter + scope columns var changesSet = schema.Schema.Clone(false); var selectTable = DbSyncAdapter.CreateChangesTable(schema, changesSet); using var dataReader = await command.ExecuteReaderAsync().ConfigureAwait(false); if (!dataReader.Read()) { dataReader.Close(); return(null); } // Create a new empty row var syncRow = selectTable.NewRow(); for (var i = 0; i < dataReader.FieldCount; i++) { var columnName = dataReader.GetName(i); // if we have the tombstone value, do not add it to the table if (columnName == "sync_row_is_tombstone") { var isTombstone = Convert.ToInt64(dataReader.GetValue(i)) > 0; syncRow.RowState = isTombstone ? DataRowState.Deleted : DataRowState.Modified; continue; } if (columnName == "update_scope_id") { // var readerScopeId = dataReader.GetValue(i); continue; } var columnValueObject = dataReader.GetValue(i); var columnValue = columnValueObject == DBNull.Value ? null : columnValueObject; syncRow[columnName] = columnValue; } // if syncRow is not a deleted row, we can check for which kind of row it is. if (syncRow != null && syncRow.RowState == DataRowState.Unchanged) { syncRow.RowState = DataRowState.Modified; } dataReader.Close(); return(syncRow); }
/// <summary> /// Reset a table, deleting rows from table and tracking_table /// </summary> internal async Task <SyncContext> InternalResetTableAsync(IScopeInfo scopeInfo, SyncContext context, DbSyncAdapter syncAdapter, DbConnection connection, DbTransaction transaction) { var(command, _) = await syncAdapter.GetCommandAsync(DbCommandType.Reset, connection, transaction); if (command != null) { await this.InterceptAsync(new DbCommandArgs(context, command, connection, transaction)).ConfigureAwait(false); await command.ExecuteNonQueryAsync().ConfigureAwait(false); command.Dispose(); } return(context); }
/// <summary> /// Internal update untracked rows routine /// </summary> internal async Task <int> InternalUpdateUntrackedRowsAsync(SyncContext ctx, DbSyncAdapter syncAdapter, DbConnection connection, DbTransaction transaction) { // Get correct Select incremental changes command var command = await syncAdapter.GetCommandAsync(DbCommandType.UpdateUntrackedRows, connection, transaction); // Execute var rowAffected = await command.ExecuteNonQueryAsync().ConfigureAwait(false); // Check if we have a return value instead var syncRowCountParam = DbSyncAdapter.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { rowAffected = (int)syncRowCountParam.Value; } return(rowAffected); }
/// <summary> /// Internal update untracked rows routine /// </summary> internal async Task <(SyncContext context, int updated)> InternalUpdateUntrackedRowsAsync(IScopeInfo scopeInfo, SyncContext context, DbSyncAdapter syncAdapter, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken = default, IProgress <ProgressArgs> progress = null) { // Get table builder var tableBuilder = this.GetTableBuilder(syncAdapter.TableDescription, scopeInfo); // Check if tracking table exists bool trackingTableExists; (context, trackingTableExists) = await this.InternalExistsTrackingTableAsync(scopeInfo, context, tableBuilder, connection, transaction, CancellationToken.None, null).ConfigureAwait(false); if (!trackingTableExists) { throw new MissingTrackingTableException(tableBuilder.TableDescription.GetFullName()); } // Get correct Select incremental changes command var(command, _) = await syncAdapter.GetCommandAsync(DbCommandType.UpdateUntrackedRows, connection, transaction); if (command == null) { return(context, 0); } await this.InterceptAsync(new DbCommandArgs(context, command, connection, transaction), progress, cancellationToken).ConfigureAwait(false); // Execute var rowAffected = await command.ExecuteNonQueryAsync().ConfigureAwait(false); // Check if we have a return value instead var syncRowCountParam = DbSyncAdapter.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { rowAffected = (int)syncRowCountParam.Value; } command.Dispose(); return(context, rowAffected); }
/// <summary> /// Update a metadata row /// </summary> internal async Task <bool> InternalUpdateMetadatasAsync(SyncContext context, DbSyncAdapter syncAdapter, SyncRow row, Guid?senderScopeId, bool forceWrite, DbConnection connection, DbTransaction transaction) { var command = await syncAdapter.GetCommandAsync(DbCommandType.UpdateMetadata, connection, transaction); // Set the parameters value from row syncAdapter.SetColumnParametersValues(command, row); // Set the special parameters for update syncAdapter.AddScopeParametersValues(command, senderScopeId, 0, row.RowState == DataRowState.Deleted, forceWrite); var metadataUpdatedRowsCount = await command.ExecuteNonQueryAsync().ConfigureAwait(false); // Check if we have a return value instead var syncRowCountParam = DbSyncAdapter.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { metadataUpdatedRowsCount = (int)syncRowCountParam.Value; } return(metadataUpdatedRowsCount > 0); }
/// <summary> /// Enabling all constraints on synced tables /// </summary> internal async Task InternalEnableConstraintsAsync(SyncContext context, DbSyncAdapter syncAdapter, DbConnection connection, DbTransaction transaction) { var command = await syncAdapter.GetCommandAsync(DbCommandType.EnableConstraints, connection, transaction).ConfigureAwait(false); await command.ExecuteNonQueryAsync().ConfigureAwait(false); }