private static async Task DeprovisionServerManuallyAsync() { // Create server provider var serverProvider = new SqlSyncProvider(serverConnectionString); // Create standard Setup and Options var setup = new SyncSetup(new string[] { "Address", "Customer", "CustomerAddress" }); var options = new SyncOptions(); // Create a server orchestrator used to Deprovision everything on the server side var remoteOrchestrator = new RemoteOrchestrator(serverProvider, options, setup); // Get the server scope var serverScope = await remoteOrchestrator.GetServerScopeAsync(); // Deprovision everything await remoteOrchestrator.DeprovisionAsync(SyncProvision.StoredProcedures | SyncProvision.Triggers | SyncProvision.TrackingTable); // Affect good values serverScope.Setup = null; serverScope.Schema = null; // save the server scope await remoteOrchestrator.SaveServerScopeAsync(serverScope); }
private static async Task DeprovisionServerManuallyAsync() { // Create server provider var serverProvider = new SqlSyncProvider(serverConnectionString); // Create standard Setup and Options var setup = new SyncSetup(new string[] { "Address", "Customer", "CustomerAddress" }); var options = new SyncOptions(); // Create a server orchestrator used to Deprovision everything on the server side var remoteOrchestrator = new RemoteOrchestrator(serverProvider, options, setup); // Deprovision everything await remoteOrchestrator.DeprovisionAsync(); }
private static async Task DeprovisionServerManuallyAsync() { // Create server provider var serverProvider = new SqlSyncProvider(serverConnectionString); // Create a server orchestrator used to Deprovision everything on the server side var remoteOrchestrator = new RemoteOrchestrator(serverProvider); // Deprovision everything var p = SyncProvision.ServerScope | SyncProvision.ServerHistoryScope | SyncProvision.StoredProcedures | SyncProvision.TrackingTable | SyncProvision.Triggers; // Deprovision everything await remoteOrchestrator.DeprovisionAsync(p); }
private static async Task SynchronizeThenDeprovisionThenProvisionAsync() { // Create 2 Sql Sync providers var serverProvider = new SqlSyncProvider(serverConnectionString); var clientProvider = new SqlSyncProvider(clientConnectionString); // Create standard Setup and Options var setup = new SyncSetup(new string[] { "Address", "Customer", "CustomerAddress" }); var options = new SyncOptions(); // Creating an agent that will handle all the process var agent = new SyncAgent(clientProvider, serverProvider, options, setup); // Using the Progress pattern to handle progession during the synchronization var progress = new SynchronousProgress <ProgressArgs>(args => Console.WriteLine($"{args.ProgressPercentage:p}:\t{args.Message}")); // First sync to have a starting point var s1 = await agent.SynchronizeAsync(progress); Console.WriteLine(s1); // ----------------------------------------------------------------- // Migrating a table by adding a new column // ----------------------------------------------------------------- // Adding a new column called CreatedDate to Address table, on the server, and on the client. await Helper.AddNewColumnToAddressAsync(serverProvider.CreateConnection()); await Helper.AddNewColumnToAddressAsync(clientProvider.CreateConnection()); // ----------------------------------------------------------------- // Server side // ----------------------------------------------------------------- // Creating a setup regarding only the table Address var setupAddress = new SyncSetup(new string[] { "Address" }); // Create a server orchestrator used to Deprovision and Provision only table Address var remoteOrchestrator = new RemoteOrchestrator(serverProvider, options, setupAddress); // Unprovision the old Address triggers / stored proc. // We can conserve the Address tracking table, since we just add a column, // that is not a primary key used in the tracking table // That way, we are preserving historical data await remoteOrchestrator.DeprovisionAsync(SyncProvision.StoredProcedures | SyncProvision.Triggers); // Provision the new Address triggers / stored proc again, // This provision method will fetch the address schema from the database, // so it will contains all the columns, including the new Address column added await remoteOrchestrator.ProvisionAsync(SyncProvision.StoredProcedures | SyncProvision.Triggers); // ----------------------------------------------------------------- // Client side // ----------------------------------------------------------------- // Now go for local orchestrator var localOrchestrator = new LocalOrchestrator(clientProvider, options, setupAddress); // Unprovision the Address triggers / stored proc. We can conserve tracking table, since we just add a column, that is not a primary key used in the tracking table // In this case, we will await localOrchestrator.DeprovisionAsync(SyncProvision.StoredProcedures | SyncProvision.Triggers); // Provision the Address triggers / stored proc again, // This provision method will fetch the address schema from the database, so it will contains all the columns, including the new one added await localOrchestrator.ProvisionAsync(SyncProvision.StoredProcedures | SyncProvision.Triggers); // Now test a new sync, everything should work as expected. do { // Console.Clear(); Console.WriteLine("Sync Start"); try { var s2 = await agent.SynchronizeAsync(); // Write results Console.WriteLine(s2); } catch (Exception e) { Console.WriteLine(e.Message); } } while (Console.ReadKey().Key != ConsoleKey.Escape); Console.WriteLine("End"); }
private static async Task SynchronizeThenDeprovisionThenProvisionAsync() { // Create 2 Sql Sync providers var serverProvider = new SqlSyncProvider(DBHelper.GetDatabaseConnectionString(serverDbName)); var clientProvider = new SqlSyncProvider(DBHelper.GetDatabaseConnectionString(clientDbName)); // Create standard Setup and Options var setup = new SyncSetup(new string[] { "Address", "Customer", "CustomerAddress" }); var options = new SyncOptions(); // Creating an agent that will handle all the process var agent = new SyncAgent(clientProvider, serverProvider, options, setup); // Using the Progress pattern to handle progession during the synchronization var progress = new SynchronousProgress <ProgressArgs>(s => Console.WriteLine($"{s.Context.SyncStage}:\t{s.Message}")); // First sync to have a starting point var s1 = await agent.SynchronizeAsync(progress); Console.WriteLine(s1); // ----------------------------------------------------------------- // Migrating a table by adding a new column // ----------------------------------------------------------------- // Adding a new column called CreatedDate to Address table, on the server, and on the client. await AddNewColumnToAddressAsync(serverProvider.CreateConnection()); await AddNewColumnToAddressAsync(clientProvider.CreateConnection()); // ----------------------------------------------------------------- // Server side // ----------------------------------------------------------------- // Creating a setup regarding only the table Address var setupAddress = new SyncSetup(new string[] { "Address" }); // Create a server orchestrator used to Deprovision and Provision only table Address var remoteOrchestrator = new RemoteOrchestrator(serverProvider, options, setupAddress); // Unprovision the Address triggers / stored proc. // We can conserve the Address tracking table, since we just add a column, // that is not a primary key used in the tracking table // That way, we are preserving historical data await remoteOrchestrator.DeprovisionAsync(SyncProvision.StoredProcedures | SyncProvision.Triggers); // Provision the Address triggers / stored proc again, // This provision method will fetch the address schema from the database, // so it will contains all the columns, including the new Address column added await remoteOrchestrator.ProvisionAsync(SyncProvision.StoredProcedures | SyncProvision.Triggers); // Now we need the full setup to get the full schema. // Setup includes [Address] [Customer] and [CustomerAddress] remoteOrchestrator.Setup = setup; var newSchema = await remoteOrchestrator.GetSchemaAsync(); // Now we need to save this new schema to the serverscope table // get the server scope again var serverScope = await remoteOrchestrator.GetServerScopeAsync(); // affect good values serverScope.Setup = setup; serverScope.Schema = newSchema; // save it await remoteOrchestrator.WriteServerScopeAsync(serverScope); // ----------------------------------------------------------------- // Client side // ----------------------------------------------------------------- // Now go for local orchestrator var localOrchestrator = new LocalOrchestrator(clientProvider, options, setupAddress); // Unprovision the Address triggers / stored proc. We can conserve tracking table, since we just add a column, that is not a primary key used in the tracking table // In this case, we will await localOrchestrator.DeprovisionAsync(SyncProvision.StoredProcedures | SyncProvision.Triggers); // Provision the Address triggers / stored proc again, // This provision method will fetch the address schema from the database, so it will contains all the columns, including the new one added await localOrchestrator.ProvisionAsync(SyncProvision.StoredProcedures | SyncProvision.Triggers); // Now we need to save this to clientscope // get the server scope again var clientScope = await localOrchestrator.GetClientScopeAsync(); // At this point, if you need the schema and you are not able to create a RemoteOrchestrator, // You can create a WebClientOrchestrator and get the schema as well // var proxyClientProvider = new WebClientOrchestrator("https://localhost:44369/api/Sync"); // var newSchema = proxyClientProvider.GetSchemaAsync(); // affect good values clientScope.Setup = setup; clientScope.Schema = newSchema; // save it await localOrchestrator.WriteClientScopeAsync(clientScope); // Now test a new sync, everything should work as expected. do { // Console.Clear(); Console.WriteLine("Sync Start"); try { var s2 = await agent.SynchronizeAsync(); // Write results Console.WriteLine(s2); } catch (Exception e) { Console.WriteLine(e.Message); } } while (Console.ReadKey().Key != ConsoleKey.Escape); Console.WriteLine("End"); }
public async Task RemoteOrchestrator_Scopes_Multiple_Check_Metadatas_Are_Deleted() { var dbName = HelperDatabase.GetRandomName("tcp_ro_"); await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true); var cs = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName); var sqlProvider = new SqlSyncProvider(cs); var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, sqlProvider), true, false); await ctx.Database.EnsureCreatedAsync(); var options = new SyncOptions(); var remoteOrchestrator = new RemoteOrchestrator(sqlProvider, options); var setup = new SyncSetup(this.Tables); var setup2 = new SyncSetup(this.Tables); setup2.Filters.Add("Customer", "EmployeeID"); var remoteScopeInfo1 = await remoteOrchestrator.GetServerScopeInfoAsync(setup); var remoteScopeInfo2 = await remoteOrchestrator.GetServerScopeInfoAsync("A", setup2); Assert.NotNull(remoteScopeInfo1.Setup); Assert.NotNull(remoteScopeInfo1.Schema); Assert.NotNull(remoteScopeInfo2.Setup); Assert.NotNull(remoteScopeInfo2.Schema); // Provision two scopes (already tested in previous test) remoteScopeInfo1 = await remoteOrchestrator.ProvisionAsync(setup); remoteScopeInfo2 = await remoteOrchestrator.ProvisionAsync("A", setup2); // Deprovision await remoteOrchestrator.DeprovisionAsync("A"); foreach (var table in remoteScopeInfo1.Setup.Tables) { var tableName = table.TableName; var schemaName = table.SchemaName; foreach (var objectSpType in Enum.GetValues(typeof(Builders.DbStoredProcedureType))) { var spType = (Builders.DbStoredProcedureType)objectSpType; var exists1 = await remoteOrchestrator.ExistStoredProcedureAsync( remoteScopeInfo1, tableName, schemaName, spType); var exists2 = await remoteOrchestrator.ExistStoredProcedureAsync( remoteScopeInfo2, tableName, schemaName, spType); if (spType == Builders.DbStoredProcedureType.SelectChangesWithFilters || spType == Builders.DbStoredProcedureType.SelectInitializedChangesWithFilters) { Assert.False(exists1); } else { Assert.True(exists1); } Assert.False(exists2); } foreach (var objectSpType in Enum.GetValues(typeof(Builders.DbTriggerType))) { var trigType = (Builders.DbTriggerType)objectSpType; var existsTrig1 = await remoteOrchestrator.ExistTriggerAsync(remoteScopeInfo1, tableName, schemaName, trigType); var existsTrig2 = await remoteOrchestrator.ExistTriggerAsync(remoteScopeInfo2, tableName, schemaName, trigType); Assert.False(existsTrig1); Assert.False(existsTrig2); } var trackTableExists1 = await remoteOrchestrator.ExistTrackingTableAsync(remoteScopeInfo1, tableName, schemaName); var trackTableExists2 = await remoteOrchestrator.ExistTrackingTableAsync(remoteScopeInfo2, tableName, schemaName); Assert.True(trackTableExists1); Assert.True(trackTableExists2); } // Deprovision await remoteOrchestrator.DeprovisionAsync(); foreach (var table in remoteScopeInfo1.Setup.Tables) { var tableName = table.TableName; var schemaName = table.SchemaName; foreach (var objectSpType in Enum.GetValues(typeof(Builders.DbStoredProcedureType))) { var spType = (Builders.DbStoredProcedureType)objectSpType; var exists1 = await remoteOrchestrator.ExistStoredProcedureAsync( remoteScopeInfo1, tableName, schemaName, spType); var exists2 = await remoteOrchestrator.ExistStoredProcedureAsync( remoteScopeInfo2, tableName, schemaName, spType); Assert.False(exists1); Assert.False(exists2); } } HelperDatabase.DropDatabase(ProviderType.Sql, dbName); }