示例#1
0
        /// <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;
            }
        }
示例#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);
        }
示例#3
0
        /// <summary>
        /// Set common parameters to SelectChanges Sql command
        /// </summary>
        private void SetSelectChangesCommonParameters(SyncContext context, SyncTable syncTable, Guid?excludingScopeId, bool isNew, long lastTimestamp, DbCommand selectIncrementalChangesCommand)
        {
            // Generate the isNewScope Flag.
            var isNewScope = isNew ? 1 : 0;
            var isReinit   = context.SyncType == SyncType.Reinitialize ? 1 : 0;

            switch (context.SyncWay)
            {
            case SyncWay.Upload:
                // Overwrite if we are in Reinitialize mode (not RenitializeWithUpload)
                isNewScope    = context.SyncType == SyncType.Reinitialize ? 1 : isNewScope;
                lastTimestamp = context.SyncType == SyncType.Reinitialize ? 0 : lastTimestamp;
                isReinit      = context.SyncType == SyncType.Reinitialize ? 1 : 0;
                break;

            case SyncWay.Download:
                // Ovewrite on bot Reinitialize and ReinitializeWithUpload
                isNewScope    = context.SyncType != SyncType.Normal ? 1 : isNewScope;
                lastTimestamp = context.SyncType != SyncType.Normal ? 0 : lastTimestamp;
                isReinit      = context.SyncType != SyncType.Normal ? 1 : 0;
                break;

            default:
                break;
            }

            // Set the parameters
            DbTableManagerFactory.SetParameterValue(selectIncrementalChangesCommand, "sync_min_timestamp", lastTimestamp);
            DbTableManagerFactory.SetParameterValue(selectIncrementalChangesCommand, "sync_scope_id", excludingScopeId.HasValue ? (object)excludingScopeId.Value : DBNull.Value);

            // Check filters
            SyncFilter tableFilter = null;

            // Sqlite does not have any filter, since he can't be server side
            if (this.CanBeServerProvider)
            {
                tableFilter = syncTable.GetFilter();
            }

            var hasFilters = tableFilter != null;

            if (!hasFilters)
            {
                return;
            }

            // context parameters can be null at some point.
            var contexParameters = context.Parameters ?? new SyncParameters();

            foreach (var filterParam in tableFilter.Parameters)
            {
                var parameter = contexParameters.FirstOrDefault(p =>
                                                                p.Name.Equals(filterParam.Name, SyncGlobalization.DataSourceStringComparison));

                object val = parameter?.Value;

                DbTableManagerFactory.SetParameterValue(selectIncrementalChangesCommand, filterParam.Name, val);
            }
        }
示例#4
0
 /// <summary>
 /// Add common parameters which could be part of the command
 /// if not found, no set done
 /// </summary>
 private void AddScopeParametersValues(DbCommand command, Guid?id, long lastTimestamp, bool isDeleted, bool forceWrite)
 {
     // Dotmim.Sync parameters
     DbTableManagerFactory.SetParameterValue(command, "sync_force_write", (forceWrite ? 1 : 0));
     DbTableManagerFactory.SetParameterValue(command, "sync_min_timestamp", lastTimestamp);
     DbTableManagerFactory.SetParameterValue(command, "sync_scope_id", id.HasValue ? (object)id.Value : DBNull.Value);
     DbTableManagerFactory.SetParameterValue(command, "sync_row_is_tombstone", isDeleted);
 }
示例#5
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);
            }
        }
示例#6
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);
            }
        }
示例#7
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);
            }
        }
示例#9
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);
        }
示例#10
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);
        }