Example #1
0
        /// <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);
        }
Example #3
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);
        }
Example #5
0
        /// <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);
        }
Example #6
0
        /// <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);
        }
Example #9
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);
        }