Exemple #1
0
        /// <summary>
        /// Be sure all tables are ready and configured for sync
        /// the ScopeSet Configuration MUST be filled by the schema form Database
        /// </summary>
        public virtual async Task <SyncContext> EnsureDatabaseAsync(SyncContext context, MessageEnsureDatabase message)
        {
            DbConnection connection = null;

            try
            {
                // Event progress
                context.SyncStage = SyncStage.DatabaseApplying;

                var script = new StringBuilder();

                // Open the connection
                using (connection = this.CreateConnection())
                {
                    await connection.OpenAsync();

                    using (var transaction = connection.BeginTransaction())
                    {
                        // Interceptor
                        var beforeArgs = new DatabaseProvisioningArgs(context, SyncProvision.All, message.Schema, connection, transaction);
                        await this.InterceptAsync(beforeArgs);

                        if (message.ScopeInfo.LastSync.HasValue && !beforeArgs.OverwriteSchema)
                        {
                            return(context);
                        }

                        // Sorting tables based on dependencies between them
                        var dmTables = message.Schema.Tables
                                       .SortByDependencies(tab => tab.ChildRelations
                                                           .Select(r => r.ChildTable));

                        foreach (var dmTable in dmTables)
                        {
                            var builder = this.GetDatabaseBuilder(dmTable);
                            // set if the builder supports creating the bulk operations proc stock
                            builder.UseBulkProcedures = this.SupportBulkOperations;

                            // adding filter
                            this.AddFilters(message.Filters, dmTable, builder);

                            context.SyncStage = SyncStage.DatabaseTableApplying;

                            // Launch any interceptor if available
                            await this.InterceptAsync(new TableProvisioningArgs(context, SyncProvision.All, dmTable, connection, transaction));

                            string currentScript = null;
                            if (beforeArgs.GenerateScript)
                            {
                                currentScript  = builder.ScriptTable(connection, transaction);
                                currentScript += builder.ScriptForeignKeys(connection, transaction);
                                script.Append(currentScript);
                            }

                            builder.Create(connection, transaction);
                            builder.CreateForeignKeys(connection, transaction);

                            // Report & Interceptor
                            context.SyncStage = SyncStage.DatabaseTableApplied;
                            var tableProvisionedArgs = new TableProvisionedArgs(context, SyncProvision.All, dmTable, connection, transaction);
                            this.ReportProgress(context, tableProvisionedArgs);
                            await this.InterceptAsync(tableProvisionedArgs);
                        }

                        // Report & Interceptor
                        context.SyncStage = SyncStage.DatabaseApplied;
                        var args = new DatabaseProvisionedArgs(context, SyncProvision.All, message.Schema, script.ToString(), connection, transaction);
                        this.ReportProgress(context, args);
                        await this.InterceptAsync(args);

                        transaction.Commit();
                    }

                    connection.Close();

                    return(context);
                }
            }
            catch (Exception ex)
            {
                throw new SyncException(ex, SyncStage.DatabaseApplying);
            }
            finally
            {
                if (connection != null && connection.State != ConnectionState.Closed)
                {
                    connection.Close();
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Be sure all tables are ready and configured for sync
        /// the ScopeSet Configuration MUST be filled by the schema form Database
        /// </summary>
        public virtual async Task <SyncContext> EnsureDatabaseAsync(SyncContext context, SyncSet schema,
                                                                    DbConnection connection, DbTransaction transaction,
                                                                    CancellationToken cancellationToken, IProgress <ProgressArgs> progress = null)
        {
            // Event progress
            context.SyncStage = SyncStage.SchemaApplying;

            var script = new StringBuilder();

            var beforeArgs = new DatabaseProvisioningArgs(context, SyncProvision.All, schema, connection, transaction);

            await this.InterceptAsync(beforeArgs).ConfigureAwait(false);

            // get Database builder
            var builder = this.GetDatabaseBuilder();

            builder.UseChangeTracking = this.UseChangeTracking;
            builder.UseBulkProcedures = this.SupportBulkOperations;

            // Initialize database if needed
            builder.EnsureDatabase(connection, transaction);

            // Sorting tables based on dependencies between them
            var schemaTables = schema.Tables
                               .SortByDependencies(tab => tab.GetRelations()
                                                   .Select(r => r.GetParentTable()));

            foreach (var schemaTable in schemaTables)
            {
                var tableBuilder = this.GetTableBuilder(schemaTable);
                // set if the builder supports creating the bulk operations proc stock
                tableBuilder.UseBulkProcedures = this.SupportBulkOperations;
                tableBuilder.UseChangeTracking = this.UseChangeTracking;

                // adding filter
                this.AddFilters(schemaTable, tableBuilder);

                context.SyncStage = SyncStage.TableSchemaApplying;

                // Launch any interceptor if available
                await this.InterceptAsync(new TableProvisioningArgs(context, SyncProvision.All, schemaTable, connection, transaction)).ConfigureAwait(false);


                tableBuilder.Create(connection, transaction);
                tableBuilder.CreateForeignKeys(connection, transaction);

                // Report & Interceptor
                context.SyncStage = SyncStage.TableSchemaApplied;
                var tableProvisionedArgs = new TableProvisionedArgs(context, SyncProvision.All, schemaTable, connection, transaction);
                this.ReportProgress(context, progress, tableProvisionedArgs);
                await this.InterceptAsync(tableProvisionedArgs).ConfigureAwait(false);
            }

            // Report & Interceptor
            context.SyncStage = SyncStage.SchemaApplied;
            var args = new DatabaseProvisionedArgs(context, SyncProvision.All, schema, script.ToString(), connection, transaction);

            this.ReportProgress(context, progress, args);
            await this.InterceptAsync(args).ConfigureAwait(false);

            await this.InterceptAsync(new TransactionCommitArgs(context, connection, transaction)).ConfigureAwait(false);

            return(context);
        }