/// <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);
        }
Exemple #4
0
        /// <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);
        }
Exemple #7
0
        /// <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);
        }
Exemple #9
0
        /// <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);
        }
Exemple #15
0
        /// <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);
            }
        }
Exemple #19
0
        /// <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);
        }
Exemple #20
0
        /// <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);
        }
Exemple #21
0
        /// <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);
        }
Exemple #22
0
        /// <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);
        }
Exemple #23
0
        /// <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);
        }
Exemple #25
0
        /// <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);
        }
Exemple #26
0
        /// <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);
        }
Exemple #27
0
        /// <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);
        }
Exemple #28
0
 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);
        }
Exemple #30
0
        /// <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);
        }