Beispiel #1
0
        private DbCommand InternalSetDeleteClientScopeInfoParameters(ClientScopeInfo clientScopeInfo, DbCommand command)
        {
            DbSyncAdapter.SetParameterValue(command, "sync_scope_id", clientScopeInfo.Id.ToString());
            DbSyncAdapter.SetParameterValue(command, "sync_scope_name", clientScopeInfo.Name);

            return(command);
        }
Beispiel #2
0
        /// <summary>
        /// Set common parameters to SelectChanges Sql command
        /// </summary>
        internal void SetSelectChangesCommonParameters(SyncContext context, SyncTable syncTable, Guid?excludingScopeId, bool isNew, long?lastTimestamp, DbCommand selectIncrementalChangesCommand)
        {
            // Set the parameters
            DbSyncAdapter.SetParameterValue(selectIncrementalChangesCommand, "sync_min_timestamp", lastTimestamp);
            DbSyncAdapter.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.Provider.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;

                DbSyncAdapter.SetParameterValue(selectIncrementalChangesCommand, filterParam.Name, val);
            }
        }
        InternalExistsServerHistoryScopeInfoAsync(string scopeId, string scopeName, SyncContext context, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress)
        {
            // Get exists command
            var scopeBuilder = this.GetScopeBuilder(this.Options.ScopeInfoTableName);

            using var existsCommand = scopeBuilder.GetCommandAsync(DbScopeCommandType.ExistServerHistoryScopeInfo, connection, transaction);

            if (existsCommand == null)
            {
                return(context, false);
            }

            DbSyncAdapter.SetParameterValue(existsCommand, "sync_scope_name", scopeName);
            DbSyncAdapter.SetParameterValue(existsCommand, "sync_scope_Id", scopeId);

            if (existsCommand == null)
            {
                return(context, false);
            }

            await this.InterceptAsync(new DbCommandArgs(context, existsCommand, connection, transaction), progress, cancellationToken).ConfigureAwait(false);

            var existsResultObject = await existsCommand.ExecuteScalarAsync().ConfigureAwait(false);

            var exists = Convert.ToInt32(existsResultObject) > 0;

            return(context, exists);
        }
        /// <summary>
        /// Set command parameters value mapped to Row
        /// </summary>
        internal void SetColumnParametersValues(DbCommand command, SyncRow row)
        {
            if (row.SchemaTable == null)
            {
                throw new ArgumentException("Schema table columns does not correspond to row values");
            }

            var schemaTable = row.SchemaTable;

            foreach (DbParameter parameter in command.Parameters)
            {
                if (!string.IsNullOrEmpty(parameter.SourceColumn))
                {
                    // foreach parameter, check if we have a column
                    var column = schemaTable.Columns[parameter.SourceColumn];

                    if (column != null)
                    {
                        object value = row[column] ?? DBNull.Value;
                        DbSyncAdapter.SetParameterValue(command, parameter.ParameterName, value);
                    }
                }
            }

            // return value
            var syncRowCountParam = DbSyncAdapter.GetParameter(command, "sync_row_count");

            if (syncRowCountParam != null)
            {
                syncRowCountParam.Direction = ParameterDirection.Output;
                syncRowCountParam.Value     = DBNull.Value;
            }
        }
 /// <summary>
 /// Add common parameters which could be part of the command
 /// if not found, no set done
 /// </summary>
 internal void AddScopeParametersValues(DbCommand command, Guid?id, long?lastTimestamp, bool isDeleted, bool forceWrite)
 {
     // Dotmim.Sync parameters
     DbSyncAdapter.SetParameterValue(command, "sync_force_write", forceWrite ? 1 : 0);
     DbSyncAdapter.SetParameterValue(command, "sync_min_timestamp", lastTimestamp.HasValue ? (object)lastTimestamp.Value : DBNull.Value);
     DbSyncAdapter.SetParameterValue(command, "sync_scope_id", id.HasValue ? (object)id.Value : DBNull.Value);
     DbSyncAdapter.SetParameterValue(command, "sync_row_is_tombstone", isDeleted);
 }
Beispiel #6
0
        InternalLoadClientScopeInfoAsync(SyncContext context, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress)
        {
            var scopeBuilder = this.GetScopeBuilder(this.Options.ScopeInfoTableName);

            using var command = scopeBuilder.GetCommandAsync(DbScopeCommandType.GetClientScopeInfo, connection, transaction);

            if (command == null)
            {
                return(context, null);
            }

            DbSyncAdapter.SetParameterValue(command, "sync_scope_name", context.ScopeName);

            var action = new ClientScopeInfoLoadingArgs(context, context.ScopeName, command, connection, transaction);

            await this.InterceptAsync(action, progress, cancellationToken).ConfigureAwait(false);

            if (action.Cancel || action.Command == null)
            {
                return(context, null);
            }

            await this.InterceptAsync(new DbCommandArgs(context, action.Command, connection, transaction), progress, cancellationToken).ConfigureAwait(false);

            using DbDataReader reader = await action.Command.ExecuteReaderAsync().ConfigureAwait(false);

            ClientScopeInfo clientScopeInfo = null;

            if (reader.Read())
            {
                clientScopeInfo = InternalReadClientScopeInfo(reader);
            }

            reader.Close();

            if (clientScopeInfo?.Schema != null)
            {
                clientScopeInfo.Schema.EnsureSchema();
            }

            if (clientScopeInfo != null)
            {
                var scopeLoadedArgs = new ClientScopeInfoLoadedArgs(context, context.ScopeName, clientScopeInfo, connection, transaction);
                await this.InterceptAsync(scopeLoadedArgs, progress, cancellationToken).ConfigureAwait(false);

                clientScopeInfo = scopeLoadedArgs.ClientScopeInfo;
            }

            action.Command.Dispose();

            return(context, clientScopeInfo);
        }
        private DbCommand InternalSetSaveServerScopeInfoParameters(ServerScopeInfo serverScopeInfo, DbCommand command)
        {
            var serializedSchema = JsonConvert.SerializeObject(serverScopeInfo.Schema);
            var serializedSetup  = JsonConvert.SerializeObject(serverScopeInfo.Setup);

            DbSyncAdapter.SetParameterValue(command, "sync_scope_name", serverScopeInfo.Name);
            DbSyncAdapter.SetParameterValue(command, "sync_scope_schema", serverScopeInfo.Schema == null ? DBNull.Value : serializedSchema);
            DbSyncAdapter.SetParameterValue(command, "sync_scope_setup", serverScopeInfo.Setup == null ? DBNull.Value : serializedSetup);
            DbSyncAdapter.SetParameterValue(command, "sync_scope_version", serverScopeInfo.Version);
            DbSyncAdapter.SetParameterValue(command, "sync_scope_last_clean_timestamp", serverScopeInfo.LastCleanupTimestamp);

            return(command);
        }
Beispiel #8
0
        private DbCommand InternalSetSaveClientScopeInfoParameters(ClientScopeInfo clientScopeInfo, DbCommand command)
        {
            DbSyncAdapter.SetParameterValue(command, "sync_scope_id", clientScopeInfo.Id.ToString());
            DbSyncAdapter.SetParameterValue(command, "sync_scope_name", clientScopeInfo.Name);
            DbSyncAdapter.SetParameterValue(command, "sync_scope_schema", clientScopeInfo.Schema == null ? DBNull.Value : (object)JsonConvert.SerializeObject(clientScopeInfo.Schema));
            DbSyncAdapter.SetParameterValue(command, "sync_scope_setup", clientScopeInfo.Setup == null ? DBNull.Value : (object)JsonConvert.SerializeObject(clientScopeInfo.Setup));
            DbSyncAdapter.SetParameterValue(command, "sync_scope_version", clientScopeInfo.Version);
            DbSyncAdapter.SetParameterValue(command, "scope_last_sync", clientScopeInfo.LastSync.HasValue ? (object)clientScopeInfo.LastSync.Value : DBNull.Value);
            DbSyncAdapter.SetParameterValue(command, "scope_last_sync_timestamp", clientScopeInfo.LastSyncTimestamp);
            DbSyncAdapter.SetParameterValue(command, "scope_last_server_sync_timestamp", clientScopeInfo.LastServerSyncTimestamp);
            DbSyncAdapter.SetParameterValue(command, "scope_last_sync_duration", clientScopeInfo.LastSyncDuration);

            return(command);
        }
        internal virtual async Task <DatabaseMetadatasCleaned> InternalDeleteMetadatasAsync(SyncContext context, SyncSet schema, SyncSetup setup, long timestampLimit,
                                                                                            DbConnection connection, DbTransaction transaction,
                                                                                            CancellationToken cancellationToken, IProgress <ProgressArgs> progress)
        {
            await this.InterceptAsync(new MetadataCleaningArgs(context, this.Setup, timestampLimit, connection, transaction), cancellationToken).ConfigureAwait(false);

            DatabaseMetadatasCleaned databaseMetadatasCleaned = new DatabaseMetadatasCleaned {
                TimestampLimit = timestampLimit
            };

            foreach (var syncTable in schema.Tables)
            {
                // Create sync adapter
                var syncAdapter = this.GetSyncAdapter(syncTable, setup);

                var command = await syncAdapter.GetCommandAsync(DbCommandType.DeleteMetadata, connection, transaction);

                // Set the special parameters for delete metadata
                DbSyncAdapter.SetParameterValue(command, "sync_row_timestamp", timestampLimit);

                var rowsCleanedCount = await command.ExecuteNonQueryAsync().ConfigureAwait(false);

                // Check if we have a return value instead
                var syncRowCountParam = DbSyncAdapter.GetParameter(command, "sync_row_count");

                if (syncRowCountParam != null)
                {
                    rowsCleanedCount = (int)syncRowCountParam.Value;
                }

                // Only add a new table metadata stats object, if we have, at least, purged 1 or more rows
                if (rowsCleanedCount > 0)
                {
                    var tableMetadatasCleaned = new TableMetadatasCleaned(syncTable.TableName, syncTable.SchemaName)
                    {
                        RowsCleanedCount = rowsCleanedCount,
                        TimestampLimit   = timestampLimit
                    };

                    databaseMetadatasCleaned.Tables.Add(tableMetadatasCleaned);
                }
            }

            await this.InterceptAsync(new MetadataCleanedArgs(context, databaseMetadatasCleaned, connection), cancellationToken).ConfigureAwait(false);

            return(databaseMetadatasCleaned);
        }
Beispiel #10
0
        /// <summary>
        /// Internal load all scopes routine
        /// </summary>
        internal async Task <List <T> > InternalGetAllScopesAsync <T>(SyncContext ctx, DbScopeType scopeType, string scopeName, DbScopeBuilder scopeBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) where T : class
        {
            var command = scopeBuilder.GetCommandAsync(DbScopeCommandType.GetScopes, scopeType, connection, transaction);

            if (command == null)
            {
                return(null);
            }

            DbSyncAdapter.SetParameterValue(command, "sync_scope_name", scopeName);

            var action = new ScopeLoadingArgs(ctx, scopeName, scopeType, command, connection, transaction);

            await this.InterceptAsync(action, cancellationToken).ConfigureAwait(false);

            if (action.Cancel || action.Command == null)
            {
                return(null);
            }

            var scopes = new List <T>();

            using DbDataReader reader = await action.Command.ExecuteReaderAsync().ConfigureAwait(false);

            while (reader.Read())
            {
                T scopeInfo = scopeType switch
                {
                    DbScopeType.Server => ReaderServerScopeInfo(reader) as T,
                    DbScopeType.ServerHistory => ReadServerHistoryScopeInfo(reader) as T,
                    DbScopeType.Client => ReadScopeInfo(reader) as T,
                    _ => throw new NotImplementedException($"Can't get {scopeType} from the reader ")
                };

                if (scopeInfo != null)
                {
                    scopes.Add(scopeInfo);
                }
            }

            reader.Close();

            return(scopes);
        }
Beispiel #11
0
        /// <summary>
        /// Internal exists scope
        /// </summary>
        internal async Task <bool> InternalExistsScopeInfoAsync(SyncContext ctx, DbScopeType scopeType, string scopeId, DbScopeBuilder scopeBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress)
        {
            // Get exists command
            var existsCommand = scopeBuilder.GetCommandAsync(DbScopeCommandType.ExistScope, scopeType, connection, transaction);

            // Just in case, in older version we may have sync_scope_name as primary key;
            DbSyncAdapter.SetParameterValue(existsCommand, "sync_scope_name", scopeId);
            // Set primary key value
            DbSyncAdapter.SetParameterValue(existsCommand, "sync_scope_id", scopeId);

            if (existsCommand == null)
            {
                return(false);
            }

            var existsResultObject = await existsCommand.ExecuteScalarAsync().ConfigureAwait(false);

            var exists = Convert.ToInt32(existsResultObject) > 0;

            return(exists);
        }
        InternalLoadServerHistoryScopeAsync(string scopeId, SyncContext context, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress)
        {
            var scopeBuilder = this.GetScopeBuilder(this.Options.ScopeInfoTableName);

            using var command = scopeBuilder.GetCommandAsync(DbScopeCommandType.GetServerHistoryScopeInfo, connection, transaction);

            if (command == null)
            {
                return(context, null);
            }

            DbSyncAdapter.SetParameterValue(command, "sync_scope_id", scopeId);
            DbSyncAdapter.SetParameterValue(command, "sync_scope_name", context.ScopeName);

            await this.InterceptAsync(new DbCommandArgs(context, command, connection, transaction), progress, cancellationToken).ConfigureAwait(false);

            using DbDataReader reader = await command.ExecuteReaderAsync().ConfigureAwait(false);

            ServerHistoryScopeInfo serverHistoryScopeInfo = null;

            if (reader.Read())
            {
                serverHistoryScopeInfo = InternalReadServerHistoryScopeInfo(reader);
            }

            reader.Close();

            if (serverHistoryScopeInfo.Schema != null)
            {
                serverHistoryScopeInfo.Schema.EnsureSchema();
            }

            command.Dispose();

            return(context, serverHistoryScopeInfo);
        }
Beispiel #13
0
        InternalDeleteMetadatasAsync(
            IEnumerable <IScopeInfo> scopeInfos, SyncContext context, long timestampLimit,
            DbConnection connection, DbTransaction transaction,
            CancellationToken cancellationToken, IProgress <ProgressArgs> progress)
        {
            context.SyncStage = SyncStage.ChangesApplying;

            var databaseMetadatasCleaned = new DatabaseMetadatasCleaned {
                TimestampLimit = timestampLimit
            };

            await this.InterceptAsync(new MetadataCleaningArgs(context, scopeInfos, timestampLimit,
                                                               connection, transaction), progress, cancellationToken).ConfigureAwait(false);

            // contains all tables already processed
            var doneList = new List <SetupTable>();

            foreach (var scopeInfo in scopeInfos)
            {
                if (scopeInfo.Setup?.Tables == null || scopeInfo.Setup.Tables.Count <= 0)
                {
                    continue;
                }

                foreach (var setupTable in scopeInfo.Setup.Tables)
                {
                    var isDone = doneList.Any(t => t.EqualsByName(setupTable));

                    if (isDone)
                    {
                        continue;
                    }

                    // create a fake syncTable
                    // Don't need anything else than table name to make a delete metadata clean up
                    var syncTable = new SyncTable(setupTable.TableName, setupTable.SchemaName);

                    // Create sync adapter
                    var syncAdapter = this.GetSyncAdapter(syncTable, scopeInfo);

                    var(command, _) = await syncAdapter.GetCommandAsync(DbCommandType.DeleteMetadata, connection, transaction);

                    if (command != null)
                    {
                        // Set the special parameters for delete metadata
                        DbSyncAdapter.SetParameterValue(command, "sync_row_timestamp", timestampLimit);

                        await this.InterceptAsync(new DbCommandArgs(context, command, connection, transaction), progress, cancellationToken).ConfigureAwait(false);

                        var rowsCleanedCount = await command.ExecuteNonQueryAsync().ConfigureAwait(false);

                        // Check if we have a return value instead
                        var syncRowCountParam = DbSyncAdapter.GetParameter(command, "sync_row_count");

                        if (syncRowCountParam != null)
                        {
                            rowsCleanedCount = (int)syncRowCountParam.Value;
                        }

                        // Only add a new table metadata stats object, if we have, at least, purged 1 or more rows
                        if (rowsCleanedCount > 0)
                        {
                            var tableMetadatasCleaned = new TableMetadatasCleaned(syncTable.TableName, syncTable.SchemaName)
                            {
                                RowsCleanedCount = rowsCleanedCount,
                                TimestampLimit   = timestampLimit
                            };

                            databaseMetadatasCleaned.Tables.Add(tableMetadatasCleaned);
                        }

                        command.Dispose();
                    }

                    doneList.Add(setupTable);
                }
            }

            await this.InterceptAsync(new MetadataCleanedArgs(context, databaseMetadatasCleaned, connection), progress, cancellationToken).ConfigureAwait(false);

            return(context, databaseMetadatasCleaned);
        }