/// <summary> /// Internal drop trigger routine /// </summary> internal async Task <(SyncContext context, bool dropped)> InternalDropTriggerAsync( IScopeInfo scopeInfo, SyncContext context, DbTableBuilder tableBuilder, DbTriggerType triggerType, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { using var command = await tableBuilder.GetDropTriggerCommandAsync(triggerType, connection, transaction).ConfigureAwait(false); if (command == null) { return(context, false); } var action = await this.InterceptAsync(new TriggerDroppingArgs(context, tableBuilder.TableDescription, triggerType, command, connection, transaction), progress, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(context, false); } await this.InterceptAsync(new DbCommandArgs(context, action.Command, connection, transaction), progress, cancellationToken).ConfigureAwait(false); await action.Command.ExecuteNonQueryAsync(); await this.InterceptAsync(new TriggerDroppedArgs(context, tableBuilder.TableDescription, triggerType, connection, transaction), progress, cancellationToken).ConfigureAwait(false); action.Command.Dispose(); return(context, true); }
/// <summary> /// Internal drop triggers routine /// </summary> internal async Task <bool> InternalDropTriggersAsync(SyncContext ctx, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { var hasDroppeAtLeastOneTrigger = false; var listTriggerType = Enum.GetValues(typeof(DbTriggerType)); foreach (DbTriggerType triggerType in listTriggerType) { var exists = await InternalExistsTriggerAsync(ctx, tableBuilder, triggerType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (!exists) { continue; } var dropped = await InternalDropTriggerAsync(ctx, tableBuilder, triggerType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (dropped) { hasDroppeAtLeastOneTrigger = true; } } return(hasDroppeAtLeastOneTrigger); }
/// <summary> /// Internal drop tracking table routine /// </summary> internal async Task <bool> InternalDropTrackingTableAsync(SyncContext ctx, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { var command = await tableBuilder.GetDropTrackingTableCommandAsync(connection, transaction).ConfigureAwait(false); if (command == null) { return(false); } var(_, trackingTableName) = this.Provider.GetParsers(tableBuilder.TableDescription, this.Setup); var action = new TrackingTableDroppingArgs(ctx, tableBuilder.TableDescription, trackingTableName, command, connection, transaction); await this.InterceptAsync(action, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(false); } await action.Command.ExecuteNonQueryAsync().ConfigureAwait(false); await this.InterceptAsync(new TrackingTableDroppedArgs(ctx, tableBuilder.TableDescription, trackingTableName, connection, transaction), cancellationToken).ConfigureAwait(false); return(true); }
/// <summary> /// Internal drop storedProcedures routine /// </summary> internal async Task <(SyncContext context, bool dropped)> InternalDropStoredProceduresAsync( IScopeInfo scopeInfo, SyncContext context, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { // check bulk before var hasDroppedAtLeastOneStoredProcedure = false; var listStoredProcedureType = Enum.GetValues(typeof(DbStoredProcedureType)).Cast <DbStoredProcedureType>().OrderBy(sp => (int)sp); foreach (DbStoredProcedureType storedProcedureType in Enum.GetValues(typeof(DbStoredProcedureType))) { bool exists; (context, exists) = await InternalExistsStoredProcedureAsync(scopeInfo, context, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (exists) { bool dropped; (context, dropped) = await InternalDropStoredProcedureAsync(scopeInfo, context, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); // If at least one stored proc has been dropped, we're good to return true; if (dropped) { hasDroppedAtLeastOneStoredProcedure = true; } } } return(context, hasDroppedAtLeastOneStoredProcedure); }
/// <summary> /// Internal drop tracking table routine /// </summary> internal async Task <(SyncContext context, bool dropped)> InternalDropTrackingTableAsync( IScopeInfo scopeInfo, SyncContext context, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { await using var runner = await this.GetConnectionAsync(context, SyncMode.Writing, SyncStage.Deprovisioning, connection, transaction, cancellationToken, progress).ConfigureAwait(false); using var command = await tableBuilder.GetDropTrackingTableCommandAsync(connection, transaction).ConfigureAwait(false); if (command == null) { return(context, false); } var(_, trackingTableName) = this.Provider.GetParsers(tableBuilder.TableDescription, scopeInfo.Setup); var action = await this.InterceptAsync(new TrackingTableDroppingArgs(context, tableBuilder.TableDescription, trackingTableName, command, connection, transaction), progress, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(context, false); } await this.InterceptAsync(new DbCommandArgs(context, action.Command, connection, transaction), progress, cancellationToken).ConfigureAwait(false); await action.Command.ExecuteNonQueryAsync().ConfigureAwait(false); await this.InterceptAsync(new TrackingTableDroppedArgs(context, tableBuilder.TableDescription, trackingTableName, connection, transaction), progress, cancellationToken).ConfigureAwait(false); await runner.CommitAsync().ConfigureAwait(false); action.Command.Dispose(); return(context, true); }
/// <summary> /// Internal drop triggers routine /// </summary> internal async Task <(SyncContext context, bool dropped)> InternalDropTriggersAsync( IScopeInfo scopeInfo, SyncContext context, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { var hasDroppeAtLeastOneTrigger = false; var listTriggerType = Enum.GetValues(typeof(DbTriggerType)); foreach (DbTriggerType triggerType in listTriggerType) { bool exists; (context, exists) = await InternalExistsTriggerAsync(scopeInfo, context, tableBuilder, triggerType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (!exists) { continue; } bool dropped; (context, dropped) = await InternalDropTriggerAsync(scopeInfo, context, tableBuilder, triggerType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (dropped) { hasDroppeAtLeastOneTrigger = true; } } return(context, hasDroppeAtLeastOneTrigger); }
/// <summary> /// Internal drop storedProcedure routine /// </summary> internal async Task <bool> InternalDropStoredProcedureAsync(SyncContext ctx, DbTableBuilder tableBuilder, DbStoredProcedureType storedProcedureType, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { var filter = tableBuilder.TableDescription.GetFilter(); var command = await tableBuilder.GetDropStoredProcedureCommandAsync(storedProcedureType, filter, connection, transaction).ConfigureAwait(false); if (command == null) { return(false); } var action = new StoredProcedureDroppingArgs(ctx, tableBuilder.TableDescription, storedProcedureType, command, connection, transaction); await this.InterceptAsync(action, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(false); } await action.Command.ExecuteNonQueryAsync(); await this.InterceptAsync(new StoredProcedureDroppedArgs(ctx, tableBuilder.TableDescription, storedProcedureType, connection, transaction), cancellationToken).ConfigureAwait(false); return(true); }
/// <summary> /// Internal create trigger routine /// </summary> internal async Task <bool> InternalCreateTriggerAsync(SyncContext ctx, DbTableBuilder tableBuilder, DbTriggerType triggerType, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { if (tableBuilder.TableDescription.Columns.Count <= 0) { throw new MissingsColumnException(tableBuilder.TableDescription.GetFullName()); } if (tableBuilder.TableDescription.PrimaryKeys.Count <= 0) { throw new MissingPrimaryKeyException(tableBuilder.TableDescription.GetFullName()); } var command = await tableBuilder.GetCreateTriggerCommandAsync(triggerType, connection, transaction).ConfigureAwait(false); if (command == null) { return(false); } var action = new TriggerCreatingArgs(ctx, tableBuilder.TableDescription, triggerType, command, connection, transaction); await this.InterceptAsync(action, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(false); } await action.Command.ExecuteNonQueryAsync(); await this.InterceptAsync(new TriggerCreatedArgs(ctx, tableBuilder.TableDescription, triggerType, connection, transaction), cancellationToken).ConfigureAwait(false); return(true); }
/// <summary> /// Adding filters to an existing configuration /// </summary> private void AddFilters(SyncTable schemaTable, DbTableBuilder builder) { var schema = schemaTable.Schema; if (schema.Filters != null && schema.Filters.Count > 0) { // get the all the filters for the table builder.Filter = schemaTable.GetFilter(); } }
/// <summary> /// Adding filters to an existing configuration /// </summary> private void AddFilters(SyncTable schemaTable, DbTableBuilder builder) { var schema = schemaTable.Schema; if (schema.Filters != null && schema.Filters.Count > 0) { // get the all the filters for the table builder.Filter = schemaTable.GetFilter(); this.Orchestrator.logger.LogDebug(SyncEventsId.AddFilter, builder.Filter); } }
/// <summary> /// Rename a tracking table /// </summary> /// <param name="table">A table from your Setup instance you want to rename the tracking table</param> //public async Task<bool> RenameTrackingTableAsync(SyncTable syncTable, ParserName oldTrackingTableName, DbConnection connection = default, DbTransaction transaction = default, CancellationToken cancellationToken = default, IProgress<ProgressArgs> progress = null) //{ // try // { // await using var runner = await this.GetConnectionAsync(scopeName, SyncMode.Writing, SyncStage.Provisioning, connection, transaction, cancellationToken, progress).ConfigureAwait(false); // var tableBuilder = this.GetTableBuilder(syncTable, this.Setup); // await InternalRenameTrackingTableAsync(this.GetContext(), this.Setup, oldTrackingTableName, tableBuilder, runner.Connection, runner.Transaction, cancellationToken, progress).ConfigureAwait(false); // await runner.CommitAsync().ConfigureAwait(false); // return true; // } // catch (Exception ex) // { // throw GetSyncError(ex); // } //} /// <summary> /// Internal create tracking table routine /// </summary> internal async Task <(SyncContext context, bool crated)> InternalCreateTrackingTableAsync( IScopeInfo scopeInfo, SyncContext context, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { if (Provider == null) { throw new MissingProviderException(nameof(InternalCreateTrackingTableAsync)); } await using var runner = await this.GetConnectionAsync(context, SyncMode.Writing, SyncStage.Provisioning, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (tableBuilder.TableDescription.Columns.Count <= 0) { throw new MissingsColumnException(tableBuilder.TableDescription.GetFullName()); } if (tableBuilder.TableDescription.PrimaryKeys.Count <= 0) { throw new MissingPrimaryKeyException(tableBuilder.TableDescription.GetFullName()); } using var command = await tableBuilder.GetCreateTrackingTableCommandAsync(connection, transaction).ConfigureAwait(false); if (command == null) { return(context, false); } var(_, trackingTableName) = this.Provider.GetParsers(tableBuilder.TableDescription, scopeInfo.Setup); var action = await this.InterceptAsync(new TrackingTableCreatingArgs(context, tableBuilder.TableDescription, trackingTableName, command, connection, transaction), progress, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(context, false); } await this.InterceptAsync(new DbCommandArgs(context, action.Command, connection, transaction), progress, cancellationToken).ConfigureAwait(false); await action.Command.ExecuteNonQueryAsync().ConfigureAwait(false); await this.InterceptAsync(new TrackingTableCreatedArgs(context, tableBuilder.TableDescription, trackingTableName, connection, transaction), progress, cancellationToken).ConfigureAwait(false); await runner.CommitAsync().ConfigureAwait(false); action.Command.Dispose(); return(context, true); }
/// <summary> /// Internal exists trigger procedure routine /// </summary> internal async Task <bool> InternalExistsTriggerAsync(SyncContext ctx, DbTableBuilder tableBuilder, DbTriggerType triggerType, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { // Get exists command var existsCommand = await tableBuilder.GetExistsTriggerCommandAsync(triggerType, connection, transaction).ConfigureAwait(false); if (existsCommand == null) { return(false); } var existsResultObject = await existsCommand.ExecuteScalarAsync().ConfigureAwait(false); var exists = Convert.ToInt32(existsResultObject) > 0; return(exists); }
/// <summary> /// Internal exists trigger procedure routine /// </summary> internal async Task <(SyncContext context, bool exists)> InternalExistsTriggerAsync( IScopeInfo scopeInfo, SyncContext context, DbTableBuilder tableBuilder, DbTriggerType triggerType, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { // Get exists command using var existsCommand = await tableBuilder.GetExistsTriggerCommandAsync(triggerType, connection, transaction).ConfigureAwait(false); 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> /// Internal exists schema procedure routine /// </summary> internal async Task <bool> InternalExistsSchemaAsync(SyncContext ctx, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { if (string.IsNullOrEmpty(tableBuilder.TableDescription.SchemaName) || tableBuilder.TableDescription.SchemaName == "dbo") { return(true); } // Get exists command var existsCommand = await tableBuilder.GetExistsSchemaCommandAsync(connection, transaction).ConfigureAwait(false); if (existsCommand == null) { return(false); } var existsResultObject = await existsCommand.ExecuteScalarAsync().ConfigureAwait(false); var exists = Convert.ToInt32(existsResultObject) > 0; return(exists); }
/// <summary> /// Check then add primary keys to schema table /// </summary> private async Task SetPrimaryKeysAsync(SyncTable schemaTable, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction) { // Get PrimaryKey var schemaPrimaryKeys = await tableBuilder.GetPrimaryKeysAsync(connection, transaction).ConfigureAwait(false); if (schemaPrimaryKeys == null || schemaPrimaryKeys.Any() == false) { throw new MissingPrimaryKeyException(schemaTable.TableName); } // Set the primary Key foreach (var rowColumn in schemaPrimaryKeys.OrderBy(r => r.Ordinal)) { // Find the column in the schema columns var columnKey = schemaTable.Columns.FirstOrDefault(sc => sc.EqualsByName(rowColumn)); if (columnKey == null) { throw new MissingPrimaryKeyColumnException(rowColumn.ColumnName, schemaTable.TableName); } schemaTable.PrimaryKeys.Add(columnKey.ColumnName); } }
/// <summary> /// Internal create triggers routine /// </summary> internal async Task <(SyncContext context, bool created)> InternalCreateTriggersAsync( IScopeInfo scopeInfo, SyncContext context, bool overwrite, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { var hasCreatedAtLeastOneTrigger = false; var listTriggerType = Enum.GetValues(typeof(DbTriggerType)); foreach (DbTriggerType triggerType in listTriggerType) { bool exists; (context, exists) = await InternalExistsTriggerAsync(scopeInfo, context, tableBuilder, triggerType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); // Drop trigger if already exists if (exists && overwrite) { (context, _) = await InternalDropTriggerAsync(scopeInfo, context, tableBuilder, triggerType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); } var shouldCreate = !exists || overwrite; if (!shouldCreate) { continue; } bool hasBeenCreated; (context, hasBeenCreated) = await InternalCreateTriggerAsync(scopeInfo, context, tableBuilder, triggerType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (hasBeenCreated) { hasCreatedAtLeastOneTrigger = true; } } return(context, hasCreatedAtLeastOneTrigger); }
/// <summary> /// Internal create table routine /// </summary> internal async Task <bool> InternalCreateSchemaAsync(SyncContext ctx, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { var command = await tableBuilder.GetCreateSchemaCommandAsync(connection, transaction).ConfigureAwait(false); if (command == null) { return(false); } var action = new SchemaNameCreatingArgs(ctx, tableBuilder.TableDescription, command, connection, transaction); await this.InterceptAsync(action, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(false); } await action.Command.ExecuteNonQueryAsync().ConfigureAwait(false); await this.InterceptAsync(new SchemaNameCreatedArgs(ctx, tableBuilder.TableDescription, connection, transaction), cancellationToken).ConfigureAwait(false); return(true); }
/// <summary> /// Check then add primary keys to schema table /// </summary> private async Task SetPrimaryKeysAsync(SyncTable schemaTable, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction) { // Get PrimaryKey var schemaPrimaryKeys = await tableBuilder.GetPrimaryKeysAsync(connection, transaction).ConfigureAwait(false); if (schemaPrimaryKeys == null || schemaPrimaryKeys.Any() == false) { throw new MissingPrimaryKeyException(schemaTable.TableName); } // Set the primary Key foreach (var rowColumn in schemaPrimaryKeys.OrderBy(r => r.Ordinal)) { // Find the column in the schema columns var columnKey = schemaTable.Columns.FirstOrDefault(sc => sc.EqualsByName(rowColumn)); if (columnKey == null) { throw new MissingPrimaryKeyColumnException(rowColumn.ColumnName, schemaTable.TableName); } var columnNameLower = columnKey.ColumnName.ToLowerInvariant(); if (columnNameLower == "update_scope_id" || columnNameLower == "timestamp" || columnNameLower == "timestamp_bigint" || columnNameLower == "sync_row_is_tombstone" || columnNameLower == "last_change_datetime" ) { throw new UnsupportedPrimaryKeyColumnNameException(schemaTable.GetFullName(), columnKey.ColumnName, columnKey.OriginalTypeName, this.Provider.GetProviderTypeName()); } schemaTable.PrimaryKeys.Add(columnKey.ColumnName); } }
/// <summary> /// Internal create storedProcedures routine /// </summary> internal async Task <(SyncContext context, bool created)> InternalCreateStoredProceduresAsync( IScopeInfo scopeInfo, SyncContext context, bool overwrite, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { var hasCreatedAtLeastOneStoredProcedure = false; // Order Asc is the correct order to Delete var listStoredProcedureType = Enum.GetValues(typeof(DbStoredProcedureType)).Cast <DbStoredProcedureType>().OrderBy(sp => (int)sp); // we need to drop bulk in order to be sure bulk type is delete after all if (overwrite) { foreach (DbStoredProcedureType storedProcedureType in listStoredProcedureType) { bool exists; (context, exists) = await InternalExistsStoredProcedureAsync(scopeInfo, context, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (exists) { (context, _) = await InternalDropStoredProcedureAsync(scopeInfo, context, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); } } } // Order Desc is the correct order to Create listStoredProcedureType = Enum.GetValues(typeof(DbStoredProcedureType)).Cast <DbStoredProcedureType>().OrderByDescending(sp => (int)sp); foreach (DbStoredProcedureType storedProcedureType in listStoredProcedureType) { // check with filter if ((storedProcedureType is DbStoredProcedureType.SelectChangesWithFilters || storedProcedureType is DbStoredProcedureType.SelectInitializedChangesWithFilters) && tableBuilder.TableDescription.GetFilter() == null) { continue; } bool exists; (context, exists) = await InternalExistsStoredProcedureAsync(scopeInfo, context, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); // Drop storedProcedure if already exists if (exists && overwrite) { (context, _) = await InternalDropStoredProcedureAsync(scopeInfo, context, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); } var shouldCreate = !exists || overwrite; if (!shouldCreate) { continue; } bool created; (context, created) = await InternalCreateStoredProcedureAsync(scopeInfo, context, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); // If at least one stored proc has been created, we're good to return true; if (created) { hasCreatedAtLeastOneStoredProcedure = true; } } return(context, hasCreatedAtLeastOneStoredProcedure); }
/// <summary> /// Internal create storedProcedures routine /// </summary> internal async Task <bool> InternalCreateStoredProceduresAsync(SyncContext ctx, bool overwrite, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { var hasCreatedAtLeastOneStoredProcedure = false; // check bulk before if (this.Provider.SupportBulkOperations) { var orderedList = new[] { DbStoredProcedureType.BulkDeleteRows, DbStoredProcedureType.BulkUpdateRows, DbStoredProcedureType.BulkTableType }; // we need to drop bulk in order to be sure bulk type is delete after all if (overwrite) { foreach (DbStoredProcedureType storedProcedureType in orderedList) { var exists = await InternalExistsStoredProcedureAsync(ctx, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (exists) { await InternalDropStoredProcedureAsync(ctx, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); } } } } var listStoredProcedureType = Enum.GetValues(typeof(DbStoredProcedureType)); foreach (DbStoredProcedureType storedProcedureType in listStoredProcedureType) { // if we are iterating on bulk, but provider do not support it, just loop through and continue if ((storedProcedureType is DbStoredProcedureType.BulkTableType || storedProcedureType is DbStoredProcedureType.BulkUpdateRows || storedProcedureType is DbStoredProcedureType.BulkDeleteRows) && !this.Provider.SupportBulkOperations) { continue; } // check with filter if ((storedProcedureType is DbStoredProcedureType.SelectChangesWithFilters || storedProcedureType is DbStoredProcedureType.SelectInitializedChangesWithFilters) && tableBuilder.TableDescription.GetFilter() == null) { continue; } var exists = await InternalExistsStoredProcedureAsync(ctx, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); // Drop storedProcedure if already exists if (exists && overwrite) { await InternalDropStoredProcedureAsync(ctx, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); } var shouldCreate = !exists || overwrite; if (!shouldCreate) { continue; } var created = await InternalCreateStoredProcedureAsync(ctx, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); // If at least one stored proc has been created, we're good to return true; if (created) { hasCreatedAtLeastOneStoredProcedure = true; } } return(hasCreatedAtLeastOneStoredProcedure); }
/// <summary> /// Internal add column routine /// </summary> internal async Task <(SyncContext context, bool dropped)> InternalDropColumnAsync(IScopeInfo scopeInfo, SyncContext context, string droppedColumnName, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { if (tableBuilder.TableDescription.Columns.Count <= 0) { throw new MissingsColumnException(tableBuilder.TableDescription.GetFullName()); } if (tableBuilder.TableDescription.PrimaryKeys.Count <= 0) { throw new MissingPrimaryKeyException(tableBuilder.TableDescription.GetFullName()); } using var command = await tableBuilder.GetDropColumnCommandAsync(droppedColumnName, connection, transaction).ConfigureAwait(false); if (command == null) { return(context, false); } var(tableName, _) = this.Provider.GetParsers(tableBuilder.TableDescription, scopeInfo.Setup); var action = await this.InterceptAsync(new ColumnDroppingArgs(context, droppedColumnName, tableBuilder.TableDescription, tableName, command, connection, transaction), progress, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(context, false); } await this.InterceptAsync(new DbCommandArgs(context, action.Command, connection, transaction), progress, cancellationToken).ConfigureAwait(false); await action.Command.ExecuteNonQueryAsync().ConfigureAwait(false); await this.InterceptAsync(new ColumnDroppedArgs(context, droppedColumnName, tableBuilder.TableDescription, tableName, connection, transaction), progress, cancellationToken).ConfigureAwait(false); action.Command.Dispose(); return(context, true); }
/// <summary> /// Internal exists storedProcedure procedure routine /// </summary> internal async Task <bool> InternalExistsStoredProcedureAsync(SyncContext ctx, DbTableBuilder tableBuilder, DbStoredProcedureType storedProcedureType, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { var filter = tableBuilder.TableDescription.GetFilter(); var existsCommand = await tableBuilder.GetExistsStoredProcedureCommandAsync(storedProcedureType, filter, connection, transaction).ConfigureAwait(false); if (existsCommand == null) { return(false); } var existsResultObject = await existsCommand.ExecuteScalarAsync().ConfigureAwait(false); var exists = Convert.ToInt32(existsResultObject) > 0; return(exists); }
/// <summary> /// Internal drop storedProcedures routine /// </summary> internal async Task <bool> InternalDropStoredProceduresAsync(SyncContext ctx, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { // check bulk before var hasDroppedAtLeastOneStoredProcedure = false; if (this.Provider.SupportBulkOperations) { var orderedList = new[] { DbStoredProcedureType.BulkDeleteRows, DbStoredProcedureType.BulkUpdateRows, DbStoredProcedureType.BulkTableType }; foreach (DbStoredProcedureType storedProcedureType in orderedList) { var exists = await InternalExistsStoredProcedureAsync(ctx, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (exists) { var dropped = await InternalDropStoredProcedureAsync(ctx, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); // If at least one stored proc has been dropped, we're good to return true; if (dropped) { hasDroppedAtLeastOneStoredProcedure = true; } } } } var listStoredProcedureType = Enum.GetValues(typeof(DbStoredProcedureType)) .Cast <DbStoredProcedureType>() .Where(sp => sp != DbStoredProcedureType.BulkDeleteRows && sp != DbStoredProcedureType.BulkTableType && sp != DbStoredProcedureType.BulkUpdateRows); foreach (DbStoredProcedureType storedProcedureType in listStoredProcedureType) { // check with filter if ((storedProcedureType is DbStoredProcedureType.SelectChangesWithFilters || storedProcedureType is DbStoredProcedureType.SelectInitializedChangesWithFilters) && tableBuilder.TableDescription.GetFilter() == null) { continue; } var exists = await InternalExistsStoredProcedureAsync(ctx, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); if (!exists) { continue; } var dropped = await InternalDropStoredProcedureAsync(ctx, tableBuilder, storedProcedureType, connection, transaction, cancellationToken, progress).ConfigureAwait(false); // If at least one stored proc has been dropped, we're good to return true; if (dropped) { hasDroppedAtLeastOneStoredProcedure = true; } } return(hasDroppedAtLeastOneStoredProcedure); }
/// <summary> /// Internal exists tracking table procedure routine /// </summary> internal async Task <(SyncContext context, bool exists)> InternalExistsTrackingTableAsync(IScopeInfo scopeInfo, SyncContext context, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { await using var runner = await this.GetConnectionAsync(context, SyncMode.Reading, SyncStage.None, connection, transaction, cancellationToken, progress).ConfigureAwait(false); // Get exists command using var existsCommand = await tableBuilder.GetExistsTrackingTableCommandAsync(connection, transaction).ConfigureAwait(false); 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; await runner.CommitAsync().ConfigureAwait(false); return(context, exists); }
/// <summary> /// Internal exists schema procedure routine /// </summary> internal async Task <(SyncContext context, bool exists)> InternalExistsSchemaAsync(IScopeInfo scopeInfo, SyncContext context, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { if (string.IsNullOrEmpty(tableBuilder.TableDescription.SchemaName) || tableBuilder.TableDescription.SchemaName == "dbo") { return(context, true); } // Get exists command using var existsCommand = await tableBuilder.GetExistsSchemaCommandAsync(connection, transaction).ConfigureAwait(false); 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> /// Internal create Stored Procedure routine /// </summary> internal async Task <(SyncContext context, bool created)> InternalCreateStoredProcedureAsync(IScopeInfo scopeInfo, SyncContext context, DbTableBuilder tableBuilder, DbStoredProcedureType storedProcedureType, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { if (tableBuilder.TableDescription.Columns.Count <= 0) { throw new MissingsColumnException(tableBuilder.TableDescription.GetFullName()); } if (tableBuilder.TableDescription.PrimaryKeys.Count <= 0) { throw new MissingPrimaryKeyException(tableBuilder.TableDescription.GetFullName()); } var filter = tableBuilder.TableDescription.GetFilter(); var command = await tableBuilder.GetCreateStoredProcedureCommandAsync(storedProcedureType, filter, connection, transaction).ConfigureAwait(false); if (command == null) { return(context, false); } var action = new StoredProcedureCreatingArgs(context, tableBuilder.TableDescription, storedProcedureType, command, connection, transaction); await this.InterceptAsync(action, progress, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(context, false); } await this.InterceptAsync(new DbCommandArgs(context, action.Command, connection, transaction), progress, cancellationToken).ConfigureAwait(false); await action.Command.ExecuteNonQueryAsync().ConfigureAwait(false); await this.InterceptAsync(new StoredProcedureCreatedArgs(context, tableBuilder.TableDescription, storedProcedureType, connection, transaction), progress, cancellationToken).ConfigureAwait(false); return(context, true); }
/// <summary> /// Internal exists storedProcedure procedure routine /// </summary> internal async Task <(SyncContext context, bool exists)> InternalExistsStoredProcedureAsync(IScopeInfo scopeInfo, SyncContext context, DbTableBuilder tableBuilder, DbStoredProcedureType storedProcedureType, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { var filter = tableBuilder.TableDescription.GetFilter(); var existsCommand = await tableBuilder.GetExistsStoredProcedureCommandAsync(storedProcedureType, filter, connection, transaction).ConfigureAwait(false); 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); }
public TableProvisioningArgs(SyncContext context, SyncProvision provision, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction) : base(context, connection, transaction) { Provision = provision; TableBuilder = tableBuilder; }
/// <summary> /// Internal add column routine /// </summary> internal async Task <bool> InternalAddColumnAsync(SyncContext ctx, string addedColumnName, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { if (tableBuilder.TableDescription.Columns.Count <= 0) { throw new MissingsColumnException(tableBuilder.TableDescription.GetFullName()); } if (tableBuilder.TableDescription.PrimaryKeys.Count <= 0) { throw new MissingPrimaryKeyException(tableBuilder.TableDescription.GetFullName()); } var command = await tableBuilder.GetAddColumnCommandAsync(addedColumnName, connection, transaction).ConfigureAwait(false); if (command == null) { return(false); } var(tableName, _) = this.Provider.GetParsers(tableBuilder.TableDescription, this.Setup); var action = new ColumnCreatingArgs(ctx, addedColumnName, tableBuilder.TableDescription, tableName, command, connection, transaction); await this.InterceptAsync(action, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(false); } await action.Command.ExecuteNonQueryAsync().ConfigureAwait(false); await this.InterceptAsync(new ColumnCreatedArgs(ctx, addedColumnName, tableBuilder.TableDescription, tableName, connection, transaction), cancellationToken).ConfigureAwait(false); return(true); }
/// <summary> /// Internal rename tracking table routine /// </summary> internal async Task <bool> InternalRenameTrackingTableAsync(SyncContext ctx, SyncSetup setup, ParserName oldTrackingTableName, DbTableBuilder tableBuilder, DbConnection connection, DbTransaction transaction, CancellationToken cancellationToken, IProgress <ProgressArgs> progress) { if (tableBuilder.TableDescription.Columns.Count <= 0) { throw new MissingsColumnException(tableBuilder.TableDescription.GetFullName()); } if (tableBuilder.TableDescription.PrimaryKeys.Count <= 0) { throw new MissingPrimaryKeyException(tableBuilder.TableDescription.GetFullName()); } var command = await tableBuilder.GetRenameTrackingTableCommandAsync(oldTrackingTableName, connection, transaction).ConfigureAwait(false); if (command == null) { return(false); } var(_, trackingTableName) = this.Provider.GetParsers(tableBuilder.TableDescription, setup); var action = new TrackingTableRenamingArgs(ctx, tableBuilder.TableDescription, trackingTableName, oldTrackingTableName, command, connection, transaction); await this.InterceptAsync(action, cancellationToken).ConfigureAwait(false); if (action.Cancel || action.Command == null) { return(false); } await action.Command.ExecuteNonQueryAsync().ConfigureAwait(false); await this.InterceptAsync(new TrackingTableRenamedArgs(ctx, tableBuilder.TableDescription, trackingTableName, oldTrackingTableName, connection, transaction), cancellationToken).ConfigureAwait(false); return(true); }