/// <summary> /// Set command parameters value mapped to Row /// </summary> internal void SetColumnParametersValues(DbCommand command, SyncRow row) { if (row.Table == null) { throw new ArgumentException("Schema table columns does not correspond to row values"); } var schemaTable = row.Table; foreach (DbParameter parameter in command.Parameters) { // foreach parameter, check if we have a column if (!string.IsNullOrEmpty(parameter.SourceColumn)) { var column = schemaTable.Columns.FirstOrDefault(sc => sc.ColumnName.Equals(parameter.SourceColumn, SyncGlobalization.DataSourceStringComparison)); if (column != null) { object value = row[column] ?? DBNull.Value; DbTableManagerFactory.SetParameterValue(command, parameter.ParameterName, value); } } } // return value var syncRowCountParam = DbTableManagerFactory.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { syncRowCountParam.Direction = ParameterDirection.Output; } }
/// <summary> /// Apply a single update in the current datasource. if forceWrite, override conflict situation and force the update /// </summary> internal async Task <bool> ApplyUpdateAsync(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 this.PrepareCommandAsync(DbCommandType.UpdateRow, connection, transaction); // Set the parameters value from row this.SetColumnParametersValues(command, row); // Set the special parameters for update AddScopeParametersValues(command, senderScopeId, lastTimestamp, false, forceWrite); var rowUpdatedCount = await command.ExecuteNonQueryAsync().ConfigureAwait(false); // Check if we have a return value instead var syncRowCountParam = DbTableManagerFactory.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { rowUpdatedCount = (int)syncRowCountParam.Value; } return(rowUpdatedCount > 0); }
/// <summary> /// Apply a delete on a row /// </summary> internal async Task <bool> ApplyDeleteAsync(SyncRow row, long lastTimestamp, Guid?senderScopeId, bool forceWrite) { if (row.Table == null) { throw new ArgumentException("Schema table is not present in the row"); } using (var command = this.GetCommand(DbCommandType.DeleteRow)) { if (command == null) { throw new MissingCommandException(DbCommandType.DeleteRow.ToString()); } // Deriving Parameters await this.SetCommandParametersAsync(DbCommandType.DeleteRow, command).ConfigureAwait(false); // Set the parameters value from row this.SetColumnParametersValues(command, row); // Set the special parameters for update this.AddScopeParametersValues(command, senderScopeId, lastTimestamp, true, forceWrite); var alreadyOpened = Connection.State == ConnectionState.Open; // OPen Connection if (!alreadyOpened) { await this.Connection.OpenAsync().ConfigureAwait(false); } if (Transaction != null) { command.Transaction = Transaction; } var rowDeletedCount = await command.ExecuteNonQueryAsync().ConfigureAwait(false); // Check if we have a return value instead var syncRowCountParam = DbTableManagerFactory.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { rowDeletedCount = (int)syncRowCountParam.Value; } if (!alreadyOpened) { Connection.Close(); } return(rowDeletedCount > 0); } }
/// <summary> /// Delete all metadatas from one table before a timestamp limit /// </summary> internal async Task <int> DeleteMetadatasAsync(long timestampLimit) { using (var command = this.GetCommand(DbCommandType.DeleteMetadata)) { if (command == null) { throw new MissingCommandException(DbCommandType.DeleteMetadata.ToString()); } // Deriving Parameters await this.SetCommandParametersAsync(DbCommandType.DeleteMetadata, command).ConfigureAwait(false); // Set the special parameters for delete metadata DbTableManagerFactory.SetParameterValue(command, "sync_row_timestamp", timestampLimit); var alreadyOpened = Connection.State == ConnectionState.Open; if (!alreadyOpened) { await this.Connection.OpenAsync().ConfigureAwait(false); } if (Transaction != null) { command.Transaction = Transaction; } var metadataDeletedRowsCount = await command.ExecuteNonQueryAsync().ConfigureAwait(false); // Check if we have a return value instead var syncRowCountParam = DbTableManagerFactory.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { metadataDeletedRowsCount = (int)syncRowCountParam.Value; } if (!alreadyOpened) { Connection.Close(); } return(metadataDeletedRowsCount); } }
internal async Task <int> UpdateUntrackedRowsAsync(DbConnection connection, DbTransaction transaction) { // Get correct Select incremental changes command var command = await this.PrepareCommandAsync(DbCommandType.UpdateUntrackedRows, connection, transaction); // Execute var rowAffected = await command.ExecuteNonQueryAsync().ConfigureAwait(false); // Check if we have a return value instead var syncRowCountParam = DbTableManagerFactory.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { rowAffected = (int)syncRowCountParam.Value; } return(rowAffected); }
public virtual async Task <long> GetLocalTimestampAsync() { using (var command = connection.CreateCommand()) { bool alreadyOpened = connection.State == ConnectionState.Open; if (transaction != null) { command.Transaction = transaction; } // UPDATE Nov 2019 : We don't use min_active_rowversion anymore, since we are in a transaction // and we still need the last row version, so check back to @@DBTS command.CommandText = "SELECT @sync_new_timestamp = @@DBTS"; DbParameter p = command.CreateParameter(); p.ParameterName = "@sync_new_timestamp"; p.DbType = DbType.Int64; p.Direction = ParameterDirection.Output; command.Parameters.Add(p); if (!alreadyOpened) { await connection.OpenAsync().ConfigureAwait(false); } await command.ExecuteNonQueryAsync().ConfigureAwait(false); var outputParameter = DbTableManagerFactory.GetParameter(command, "sync_new_timestamp"); if (outputParameter == null) { return(0L); } long.TryParse(outputParameter.Value.ToString(), out long result); if (!alreadyOpened && connection.State != ConnectionState.Closed) { connection.Close(); } return(result); } }
/// <summary> /// Delete all metadatas from one table before a timestamp limit /// </summary> internal async Task <int> DeleteMetadatasAsync(long timestampLimit, DbConnection connection, DbTransaction transaction) { var command = await this.PrepareCommandAsync(DbCommandType.DeleteMetadata, connection, transaction); // Set the special parameters for delete metadata DbTableManagerFactory.SetParameterValue(command, "sync_row_timestamp", timestampLimit); var metadataDeletedRowsCount = await command.ExecuteNonQueryAsync().ConfigureAwait(false); // Check if we have a return value instead var syncRowCountParam = DbTableManagerFactory.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { metadataDeletedRowsCount = (int)syncRowCountParam.Value; } return(metadataDeletedRowsCount); }
/// <summary> /// Update a metadata row /// </summary> internal async Task <bool> UpdateMetadatasAsync(SyncRow row, Guid?senderScopeId, bool forceWrite, DbConnection connection, DbTransaction transaction) { var command = await this.PrepareCommandAsync(DbCommandType.UpdateMetadata, connection, transaction); // Set the parameters value from row this.SetColumnParametersValues(command, row); // Set the special parameters for update 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 = DbTableManagerFactory.GetParameter(command, "sync_row_count"); if (syncRowCountParam != null) { metadataUpdatedRowsCount = (int)syncRowCountParam.Value; } return(metadataUpdatedRowsCount > 0); }