/// <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;
            }
        }
Beispiel #2
0
        /// <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);
            }
        }
Beispiel #5
0
        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);
            }
        }
Beispiel #7
0
        /// <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);
        }
Beispiel #8
0
        /// <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);
        }