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); }
/// <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); }
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); }
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); }
/// <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); }
/// <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); }
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); }