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