public async Task TrackingTable_Create_All()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            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 setup   = new SyncSetup(new string[]
                                        { "SalesLT.ProductCategory", "SalesLT.ProductModel", "SalesLT.Product", "Posts" })
            {
                TrackingTablesPrefix = "t_",
                TrackingTablesSuffix = "_t"
            };

            var remoteOrchestrator = new RemoteOrchestrator(sqlProvider, options);

            var scopeInfo = await remoteOrchestrator.GetServerScopeInfoAsync(setup);

            var onCreating = 0;
            var onCreated  = 0;
            var onDropping = 0;
            var onDropped  = 0;

            remoteOrchestrator.OnTrackingTableCreating(ttca => onCreating++);
            remoteOrchestrator.OnTrackingTableCreated(ttca => onCreated++);
            remoteOrchestrator.OnTrackingTableDropping(ttca => onDropping++);
            remoteOrchestrator.OnTrackingTableDropped(ttca => onDropped++);

            await remoteOrchestrator.CreateTrackingTablesAsync(scopeInfo);

            Assert.Equal(4, onCreating);
            Assert.Equal(4, onCreated);
            Assert.Equal(0, onDropping);
            Assert.Equal(0, onDropped);

            onCreating = 0;
            onCreated  = 0;
            onDropping = 0;
            onDropped  = 0;

            await remoteOrchestrator.CreateTrackingTablesAsync(scopeInfo);

            Assert.Equal(0, onCreating);
            Assert.Equal(0, onCreated);
            Assert.Equal(0, onDropping);
            Assert.Equal(0, onDropped);

            onCreating = 0;
            onCreated  = 0;
            onDropping = 0;
            onDropped  = 0;

            await remoteOrchestrator.CreateTrackingTablesAsync(scopeInfo, true);

            Assert.Equal(4, onCreating);
            Assert.Equal(4, onCreated);
            Assert.Equal(4, onDropping);
            Assert.Equal(4, onDropped);

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
Пример #2
0
        public async Task LocalOrchestrator_ApplyChanges()
        {
            var dbNameSrv = HelperDatabase.GetRandomName("tcp_lo_srv");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbNameSrv, true);

            var dbNameCli = HelperDatabase.GetRandomName("tcp_lo_cli");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbNameCli, true);

            var csServer       = HelperDatabase.GetConnectionString(ProviderType.Sql, dbNameSrv);
            var serverProvider = new SqlSyncProvider(csServer);

            var csClient       = HelperDatabase.GetConnectionString(ProviderType.Sql, dbNameCli);
            var clientProvider = new SqlSyncProvider(csClient);

            await new AdventureWorksContext((dbNameSrv, ProviderType.Sql, serverProvider), true, false).Database.EnsureCreatedAsync();
            await new AdventureWorksContext((dbNameCli, ProviderType.Sql, clientProvider), true, false).Database.EnsureCreatedAsync();

            var scopeName   = "scopesnap1";
            var syncOptions = new SyncOptions();
            var setup       = new SyncSetup();

            // Make a first sync to be sure everything is in place
            var agent = new SyncAgent(clientProvider, serverProvider);

            // Making a first sync, will initialize everything we need
            var s = await agent.SynchronizeAsync(scopeName, this.Tables);

            // Get the orchestrators
            var localOrchestrator  = agent.LocalOrchestrator;
            var remoteOrchestrator = agent.RemoteOrchestrator;

            // Client side : Create a product category and a product
            // Create a productcategory item
            // Create a new product on server
            var productId     = Guid.NewGuid();
            var productName   = HelperDatabase.GetRandomName();
            var productNumber = productName.ToUpperInvariant().Substring(0, 10);

            var productCategoryName = HelperDatabase.GetRandomName();
            var productCategoryId   = productCategoryName.ToUpperInvariant().Substring(0, 6);

            using (var ctx = new AdventureWorksContext((dbNameSrv, ProviderType.Sql, serverProvider)))
            {
                var pc = new ProductCategory {
                    ProductCategoryId = productCategoryId, Name = productCategoryName
                };
                ctx.Add(pc);

                var product = new Product {
                    ProductId = productId, Name = productName, ProductNumber = productNumber
                };
                ctx.Add(product);

                await ctx.SaveChangesAsync();
            }

            var onDatabaseApplying = 0;
            var onDatabaseApplied  = 0;
            var onApplying         = 0;
            var onApplied          = 0;

            localOrchestrator.OnDatabaseChangesApplying(dcs =>
            {
                onDatabaseApplying++;
            });

            localOrchestrator.OnDatabaseChangesApplied(dcs =>
            {
                Assert.NotNull(dcs.ChangesApplied);
                Assert.Equal(2, dcs.ChangesApplied.TableChangesApplied.Count);
                onDatabaseApplied++;
            });


            localOrchestrator.OnTableChangesApplying(action =>
            {
                Assert.NotNull(action.SchemaTable);
                onApplying++;
            });

            localOrchestrator.OnTableChangesApplied(action =>
            {
                Assert.Equal(1, action.TableChangesApplied.Applied);
                onApplied++;
            });

            // Making a first sync, will initialize everything we need
            var s2 = await agent.SynchronizeAsync(scopeName);

            Assert.Equal(1, onDatabaseApplying);
            Assert.Equal(1, onDatabaseApplied);
            Assert.Equal(4, onApplying); // Deletes + Modified state = Table count * 2
            Assert.Equal(2, onApplied);  // Two tables applied

            HelperDatabase.DropDatabase(ProviderType.Sql, dbNameSrv);
            HelperDatabase.DropDatabase(ProviderType.Sql, dbNameCli);
        }
        public async Task RemoteOrchestrator_CreateSnapshot_WithParameters_CheckBatchInfo()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            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, true);
            await ctx.Database.EnsureCreatedAsync();

            // snapshot directory
            var snapshotDirctoryName = HelperDatabase.GetRandomName();
            var snapshotDirectory    = Path.Combine(Environment.CurrentDirectory, snapshotDirctoryName);

            var options = new SyncOptions
            {
                SnapshotsDirectory = snapshotDirectory,
                BatchSize          = 200
            };

            var setup    = new SyncSetup(Tables);
            var provider = new SqlSyncProvider(cs);

            setup.Filters.Add("Customer", "CompanyName");

            var addressCustomerFilter = new SetupFilter("CustomerAddress");

            addressCustomerFilter.AddParameter("CompanyName", "Customer");
            addressCustomerFilter.AddJoin(Join.Left, "Customer").On("CustomerAddress", "CustomerId", "Customer", "CustomerId");
            addressCustomerFilter.AddWhere("CompanyName", "Customer", "CompanyName");
            setup.Filters.Add(addressCustomerFilter);

            var addressFilter = new SetupFilter("Address");

            addressFilter.AddParameter("CompanyName", "Customer");
            addressFilter.AddJoin(Join.Left, "CustomerAddress").On("CustomerAddress", "AddressId", "Address", "AddressId");
            addressFilter.AddJoin(Join.Left, "Customer").On("CustomerAddress", "CustomerId", "Customer", "CustomerId");
            addressFilter.AddWhere("CompanyName", "Customer", "CompanyName");
            setup.Filters.Add(addressFilter);

            var orderHeaderFilter = new SetupFilter("SalesOrderHeader");

            orderHeaderFilter.AddParameter("CompanyName", "Customer");
            orderHeaderFilter.AddJoin(Join.Left, "CustomerAddress").On("CustomerAddress", "CustomerId", "SalesOrderHeader", "CustomerId");
            orderHeaderFilter.AddJoin(Join.Left, "Customer").On("CustomerAddress", "CustomerId", "Customer", "CustomerId");
            orderHeaderFilter.AddWhere("CompanyName", "Customer", "CompanyName");
            setup.Filters.Add(orderHeaderFilter);

            var orderDetailsFilter = new SetupFilter("SalesOrderDetail");

            orderDetailsFilter.AddParameter("CompanyName", "Customer");
            orderDetailsFilter.AddJoin(Join.Left, "SalesOrderHeader").On("SalesOrderDetail", "SalesOrderID", "SalesOrderHeader", "SalesOrderID");
            orderDetailsFilter.AddJoin(Join.Left, "CustomerAddress").On("CustomerAddress", "CustomerId", "SalesOrderHeader", "CustomerId");
            orderDetailsFilter.AddJoin(Join.Left, "Customer").On("CustomerAddress", "CustomerId", "Customer", "CustomerId");
            orderDetailsFilter.AddWhere("CompanyName", "Customer", "CompanyName");
            setup.Filters.Add(orderDetailsFilter);


            var orchestrator = new RemoteOrchestrator(provider, options, setup);

            SyncParameters parameters = new SyncParameters();
            var            p1         = new SyncParameter("CompanyName", "A Bike Store");

            parameters.Add(p1);

            var bi = await orchestrator.CreateSnapshotAsync(parameters);

            var finalDirectoryFullName = Path.Combine(snapshotDirectory, SyncOptions.DefaultScopeName);

            Assert.NotNull(bi);
            Assert.Equal(finalDirectoryFullName, bi.DirectoryRoot);
            Assert.Equal("CompanyName_ABikeStore", bi.DirectoryName);
            Assert.Single(bi.BatchPartsInfo);
            Assert.Equal(16, bi.BatchPartsInfo[0].Tables.Length);
            Assert.True(bi.BatchPartsInfo[0].IsLastBatch);

            // Check summary.json exists.
            var summaryFile   = Path.Combine(bi.GetDirectoryFullPath(), "summary.json");
            var summaryString = new StreamReader(summaryFile).ReadToEnd();
            var summaryObject = JObject.Parse(summaryString);

            Assert.NotNull(summaryObject);
            string summaryDirname = (string)summaryObject["dirname"];

            Assert.NotNull(summaryDirname);
            Assert.Equal("CompanyName_ABikeStore", summaryDirname);

            string summaryDir = (string)summaryObject["dir"];

            Assert.NotNull(summaryDir);
            Assert.Equal(finalDirectoryFullName, summaryDir);

            Assert.Single(summaryObject["parts"]);
            Assert.NotNull(summaryObject["parts"][0]["file"]);
            Assert.NotNull(summaryObject["parts"][0]["index"]);
            Assert.Equal(0, (int)summaryObject["parts"][0]["index"]);
            Assert.NotNull(summaryObject["parts"][0]["last"]);
            Assert.True((bool)summaryObject["parts"][0]["last"]);
            Assert.Equal(16, summaryObject["parts"][0]["tables"].Count());

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
        public async Task RemoteOrchestrator_CreateSnapshot_CheckInterceptors()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_srv");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true);

            var cs             = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName);
            var serverProvider = new SqlSyncProvider(cs);

            var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, serverProvider), true, true);
            await ctx.Database.EnsureCreatedAsync();

            var scopeName          = "scopesnap1";
            var onSnapshotCreating = false;
            var onSnapshotCreated  = false;

            // snapshot directory
            var snapshotDirctoryName = HelperDatabase.GetRandomName();
            var snapshotDirectory    = Path.Combine(Environment.CurrentDirectory, snapshotDirctoryName);

            var options = new SyncOptions
            {
                SnapshotsDirectory = snapshotDirectory,
                BatchSize          = 200
            };

            var setup = new SyncSetup(Tables);

            var remoteOrchestrator = new RemoteOrchestrator(serverProvider, options, setup, scopeName);

            // Assert on connection and transaction interceptors
            BaseOrchestratorTests.AssertConnectionAndTransaction(remoteOrchestrator, SyncStage.SnapshotCreating);

            remoteOrchestrator.OnSnapshotCreating(args =>
            {
                Assert.IsType <SnapshotCreatingArgs>(args);
                Assert.Equal(SyncStage.SnapshotCreating, args.Context.SyncStage);
                Assert.Equal(scopeName, args.Context.ScopeName);
                Assert.NotNull(args.Connection);
                Assert.NotNull(args.Transaction);
                Assert.Equal(ConnectionState.Open, args.Connection.State);
                Assert.NotNull(args.Schema);
                Assert.Equal(snapshotDirectory, args.SnapshotDirectory);
                Assert.NotEqual(0, args.Timestamp);

                onSnapshotCreating = true;
            });
            remoteOrchestrator.OnSnapshotCreated(args =>
            {
                Assert.IsType <SnapshotCreatedArgs>(args);
                Assert.Equal(SyncStage.SnapshotCreating, args.Context.SyncStage);
                Assert.Equal(scopeName, args.Context.ScopeName);
                Assert.NotNull(args.Connection);
                Assert.Null(args.Transaction);
                Assert.NotNull(args.BatchInfo);

                var finalDirectoryFullName = Path.Combine(snapshotDirectory, scopeName);

                Assert.Equal(finalDirectoryFullName, args.BatchInfo.DirectoryRoot);
                Assert.Equal("ALL", args.BatchInfo.DirectoryName);
                Assert.Single(args.BatchInfo.BatchPartsInfo);
                Assert.Equal(16, args.BatchInfo.BatchPartsInfo[0].Tables.Length);
                Assert.True(args.BatchInfo.BatchPartsInfo[0].IsLastBatch);

                onSnapshotCreated = true;
            });

            var bi = await remoteOrchestrator.CreateSnapshotAsync();

            Assert.Equal(SyncStage.SnapshotCreating, remoteOrchestrator.GetContext().SyncStage);

            Assert.True(onSnapshotCreating);
            Assert.True(onSnapshotCreated);


            var dbNameCli = HelperDatabase.GetRandomName("tcp_lo_cli");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbNameCli, true);

            var csClient       = HelperDatabase.GetConnectionString(ProviderType.Sql, dbNameCli);
            var clientProvider = new SqlSyncProvider(csClient);


            // Make a first sync to be sure everything is in place
            var agent = new SyncAgent(clientProvider, serverProvider, options, setup, scopeName);

            var onSnapshotApplying = false;
            var onSnapshotApplied  = false;



            agent.LocalOrchestrator.OnSnapshotApplying(saa =>
            {
                onSnapshotApplying = true;
            });

            agent.LocalOrchestrator.OnSnapshotApplied(saa =>
            {
                onSnapshotApplied = true;
            });


            // Making a first sync, will initialize everything we need
            await agent.SynchronizeAsync();

            Assert.True(onSnapshotApplying);
            Assert.True(onSnapshotApplied);



            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
Пример #5
0
        public async Task StoredProcedure_Create_One_Overwrite()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true);

            var cs          = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName);
            var sqlProvider = new SqlSyncProvider(cs);

            // Create default table
            var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, sqlProvider), true, false);
            await ctx.Database.EnsureCreatedAsync();

            var options = new SyncOptions();
            var setup   = new SyncSetup(new string[] { "SalesLT.Product" });

            var remoteOrchestrator = new RemoteOrchestrator(sqlProvider, options);

            var scopeInfo = await remoteOrchestrator.GetServerScopeInfoAsync(setup);

            var onCreating = 0;
            var onCreated  = 0;
            var onDropping = 0;
            var onDropped  = 0;

            remoteOrchestrator.OnStoredProcedureCreating(tca => onCreating++);
            remoteOrchestrator.OnStoredProcedureCreated(tca => onCreated++);
            remoteOrchestrator.OnStoredProcedureDropping(tca => onDropping++);
            remoteOrchestrator.OnStoredProcedureDropped(tca => onDropped++);

            var isCreated = await remoteOrchestrator.CreateStoredProcedureAsync(scopeInfo, "Product", "SalesLT", DbStoredProcedureType.SelectChanges);

            Assert.True(isCreated);
            Assert.Equal(1, onCreating);
            Assert.Equal(1, onCreated);
            Assert.Equal(0, onDropping);
            Assert.Equal(0, onDropped);

            onCreating = 0;
            onCreated  = 0;
            onDropping = 0;
            onDropped  = 0;

            isCreated = await remoteOrchestrator.CreateStoredProcedureAsync(scopeInfo, "Product", "SalesLT", DbStoredProcedureType.SelectChanges);

            Assert.False(isCreated);
            Assert.Equal(0, onCreating);
            Assert.Equal(0, onCreated);
            Assert.Equal(0, onDropping);
            Assert.Equal(0, onDropped);

            isCreated = await remoteOrchestrator.CreateStoredProcedureAsync(scopeInfo, "Product", "SalesLT", DbStoredProcedureType.SelectChanges, true);

            Assert.True(isCreated);
            Assert.Equal(1, onCreating);
            Assert.Equal(1, onCreated);
            Assert.Equal(1, onDropping);
            Assert.Equal(1, onDropped);


            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
        public async Task RemoteOrchestrator_CreateSnapshot_CheckBatchInfo()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            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, true);
            await ctx.Database.EnsureCreatedAsync();

            var rowsCount = GetServerDatabaseRowsCount((dbName, ProviderType.Sql, sqlProvider));

            var scopeName = "scopesnap2";

            // snapshot directory
            var snapshotDirctoryName = HelperDatabase.GetRandomName();
            var snapshotDirectory    = Path.Combine(Environment.CurrentDirectory, snapshotDirctoryName);

            var options = new SyncOptions
            {
                SnapshotsDirectory = snapshotDirectory,
                BatchSize          = 200
            };

            var setup    = new SyncSetup(Tables);
            var provider = new SqlSyncProvider(cs);

            var orchestrator = new RemoteOrchestrator(provider, options, setup, scopeName);

            var bi = await orchestrator.CreateSnapshotAsync();

            var finalDirectoryFullName = Path.Combine(snapshotDirectory, scopeName);

            Assert.NotNull(bi);
            Assert.Equal(finalDirectoryFullName, bi.DirectoryRoot);
            Assert.Equal("ALL", bi.DirectoryName);
            Assert.Single(bi.BatchPartsInfo);
            Assert.Equal(16, bi.BatchPartsInfo[0].Tables.Length);
            Assert.True(bi.BatchPartsInfo[0].IsLastBatch);
            Assert.Equal(rowsCount, bi.RowsCount);

            // Check summary.json exists.
            var summaryFile   = Path.Combine(bi.GetDirectoryFullPath(), "summary.json");
            var summaryString = new StreamReader(summaryFile).ReadToEnd();
            var summaryObject = JObject.Parse(summaryString);

            Assert.NotNull(summaryObject);
            string summaryDirname = (string)summaryObject["dirname"];

            Assert.NotNull(summaryDirname);
            Assert.Equal("ALL", summaryDirname);

            string summaryDir = (string)summaryObject["dir"];

            Assert.NotNull(summaryDir);
            Assert.Equal(finalDirectoryFullName, summaryDir);

            Assert.Single(summaryObject["parts"]);
            Assert.NotNull(summaryObject["parts"][0]["file"]);
            Assert.NotNull(summaryObject["parts"][0]["index"]);
            Assert.Equal(0, (int)summaryObject["parts"][0]["index"]);
            Assert.NotNull(summaryObject["parts"][0]["last"]);
            Assert.True((bool)summaryObject["parts"][0]["last"]);
            Assert.Equal(16, summaryObject["parts"][0]["tables"].Count());

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
Пример #7
0
        public async Task LocalOrchestrator_MetadataCleaning()
        {
            var dbNameSrv = HelperDatabase.GetRandomName("tcp_lo_srv");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbNameSrv, true);

            var dbNameCli = HelperDatabase.GetRandomName("tcp_lo_cli");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbNameCli, true);

            var csServer       = HelperDatabase.GetConnectionString(ProviderType.Sql, dbNameSrv);
            var serverProvider = new SqlSyncProvider(csServer);

            var csClient       = HelperDatabase.GetConnectionString(ProviderType.Sql, dbNameCli);
            var clientProvider = new SqlSyncProvider(csClient);

            await new AdventureWorksContext((dbNameSrv, ProviderType.Sql, serverProvider), true, false).Database.EnsureCreatedAsync();
            await new AdventureWorksContext((dbNameCli, ProviderType.Sql, clientProvider), true, false).Database.EnsureCreatedAsync();

            var scopeName   = "scopesnap1";
            var syncOptions = new SyncOptions();
            var setup       = new SyncSetup();

            // Make a first sync to be sure everything is in place
            var agent = new SyncAgent(clientProvider, serverProvider, this.Tables, scopeName);

            // Making a first sync, will initialize everything we need
            var s = await agent.SynchronizeAsync();

            // Get the orchestrators
            var localOrchestrator  = agent.LocalOrchestrator;
            var remoteOrchestrator = agent.RemoteOrchestrator;

            // Server side : Create a product category and a product
            // Create a productcategory item
            // Create a new product on server
            var productId     = Guid.NewGuid();
            var productName   = HelperDatabase.GetRandomName();
            var productNumber = productName.ToUpperInvariant().Substring(0, 10);

            var productCategoryName = HelperDatabase.GetRandomName();
            var productCategoryId   = productCategoryName.ToUpperInvariant().Substring(0, 6);

            using (var ctx = new AdventureWorksContext((dbNameSrv, ProviderType.Sql, serverProvider)))
            {
                var pc = new ProductCategory {
                    ProductCategoryId = productCategoryId, Name = productCategoryName
                };
                ctx.Add(pc);

                var product = new Product {
                    ProductId = productId, Name = productName, ProductNumber = productNumber
                };
                ctx.Add(product);

                await ctx.SaveChangesAsync();
            }

            var cleaning = 0;
            var cleaned  = 0;

            localOrchestrator.OnMetadataCleaning(args =>
            {
                cleaning++;
            });

            localOrchestrator.OnMetadataCleaned(args =>
            {
                cleaned++;
                Assert.Equal(0, args.DatabaseMetadatasCleaned.RowsCleanedCount);
                Assert.Empty(args.DatabaseMetadatasCleaned.Tables);
            });

            // Making a first sync, will call cleaning, but nothing is cleaned
            var s2 = await agent.SynchronizeAsync();

            Assert.Equal(1, cleaning);
            Assert.Equal(1, cleaned);

            // Reset interceptors
            localOrchestrator.OnMetadataCleaning(null);
            localOrchestrator.OnMetadataCleaned(null);
            cleaning = 0;
            cleaned  = 0;


            localOrchestrator.OnMetadataCleaning(args =>
            {
                cleaning++;
            });

            localOrchestrator.OnMetadataCleaned(args =>
            {
                cleaned++;
            });

            // Making a second empty sync.
            var s3 = await agent.SynchronizeAsync();

            // If there is no changes on any tables, no metadata cleaning is called
            Assert.Equal(0, cleaning);
            Assert.Equal(0, cleaned);


            // Server side : Create a product category
            productCategoryName = HelperDatabase.GetRandomName();
            productCategoryId   = productCategoryName.ToUpperInvariant().Substring(0, 6);

            using (var ctx = new AdventureWorksContext((dbNameSrv, ProviderType.Sql, serverProvider)))
            {
                var pc = new ProductCategory {
                    ProductCategoryId = productCategoryId, Name = productCategoryName
                };
                ctx.Add(pc);

                await ctx.SaveChangesAsync();
            }

            // Reset interceptors
            localOrchestrator.OnMetadataCleaning(null);
            localOrchestrator.OnMetadataCleaned(null);
            cleaning = 0;
            cleaned  = 0;


            localOrchestrator.OnMetadataCleaning(args =>
            {
                cleaning++;
            });

            localOrchestrator.OnMetadataCleaned(args =>
            {
                cleaned++;
                Assert.Equal(1, args.DatabaseMetadatasCleaned.RowsCleanedCount);
                Assert.Single(args.DatabaseMetadatasCleaned.Tables);
                Assert.Equal("SalesLT", args.DatabaseMetadatasCleaned.Tables[0].SchemaName);
                Assert.Equal("ProductCategory", args.DatabaseMetadatasCleaned.Tables[0].TableName);
                Assert.Equal(1, args.DatabaseMetadatasCleaned.Tables[0].RowsCleanedCount);
            });
            var s4 = await agent.SynchronizeAsync();

            Assert.Equal(1, cleaning);
            Assert.Equal(1, cleaned);


            // Server side : Create a product category and a product
            // Create a productcategory item
            // Create a new product on server
            productId     = Guid.NewGuid();
            productName   = HelperDatabase.GetRandomName();
            productNumber = productName.ToUpperInvariant().Substring(0, 10);

            productCategoryName = HelperDatabase.GetRandomName();
            productCategoryId   = productCategoryName.ToUpperInvariant().Substring(0, 6);

            using (var ctx = new AdventureWorksContext((dbNameSrv, ProviderType.Sql, serverProvider)))
            {
                var pc = new ProductCategory {
                    ProductCategoryId = productCategoryId, Name = productCategoryName
                };
                ctx.Add(pc);

                var product = new Product {
                    ProductId = productId, Name = productName, ProductNumber = productNumber
                };
                ctx.Add(product);

                await ctx.SaveChangesAsync();
            }

            // Reset interceptors
            localOrchestrator.OnMetadataCleaning(null);
            localOrchestrator.OnMetadataCleaned(null);
            cleaning = 0;
            cleaned  = 0;


            localOrchestrator.OnMetadataCleaning(args =>
            {
                cleaning++;
            });

            localOrchestrator.OnMetadataCleaned(args =>
            {
                cleaned++;
                Assert.Equal(0, args.DatabaseMetadatasCleaned.RowsCleanedCount);
            });

            var s5 = await agent.SynchronizeAsync();

            // cleaning is always called on N-1 rows, so nothing here should be called
            Assert.Equal(1, cleaning);
            Assert.Equal(1, cleaned);


            HelperDatabase.DropDatabase(ProviderType.Sql, dbNameSrv);
            HelperDatabase.DropDatabase(ProviderType.Sql, dbNameCli);
        }
Пример #8
0
        public async Task Table_Create_All()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            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 setup   = new SyncSetup(new string[] { "SalesLT.ProductCategory", "SalesLT.ProductModel", "SalesLT.Product", "Posts" });

            var localOrchestrator = new LocalOrchestrator(sqlProvider, options, setup);

            var schema = await localOrchestrator.GetSchemaAsync();

            // new empty db
            dbName = HelperDatabase.GetRandomName("tcp_lo_");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true);

            cs          = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName);
            sqlProvider = new SqlSyncProvider(cs);

            localOrchestrator = new LocalOrchestrator(sqlProvider, options, setup);


            var onCreating = 0;
            var onCreated  = 0;
            var onDropping = 0;
            var onDropped  = 0;

            localOrchestrator.OnTableCreating(ttca => onCreating++);
            localOrchestrator.OnTableCreated(ttca => onCreated++);
            localOrchestrator.OnTableDropping(ttca => onDropping++);
            localOrchestrator.OnTableDropped(ttca => onDropped++);

            await localOrchestrator.CreateTablesAsync(schema);

            Assert.Equal(4, onCreating);
            Assert.Equal(4, onCreated);
            Assert.Equal(0, onDropping);
            Assert.Equal(0, onDropped);

            onCreating = 0;
            onCreated  = 0;
            onDropping = 0;
            onDropped  = 0;

            await localOrchestrator.CreateTablesAsync(schema);

            Assert.Equal(0, onCreating);
            Assert.Equal(0, onCreated);
            Assert.Equal(0, onDropping);
            Assert.Equal(0, onDropped);

            await localOrchestrator.CreateTablesAsync(schema, true);

            Assert.Equal(4, onCreating);
            Assert.Equal(4, onCreated);
            Assert.Equal(4, onDropping);
            Assert.Equal(4, onDropped);

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
        public async Task LocalOrchestrator_GetBacthChanges()
        {
            var dbNameSrv = HelperDatabase.GetRandomName("tcp_lo_srv");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbNameSrv, true);

            var dbNameCli = HelperDatabase.GetRandomName("tcp_lo_cli");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbNameCli, true);

            var csServer       = HelperDatabase.GetConnectionString(ProviderType.Sql, dbNameSrv);
            var serverProvider = new SqlSyncProvider(csServer);

            var csClient       = HelperDatabase.GetConnectionString(ProviderType.Sql, dbNameCli);
            var clientProvider = new SqlSyncProvider(csClient);

            await new AdventureWorksContext((dbNameSrv, ProviderType.Sql, serverProvider), true, true).Database.EnsureCreatedAsync();
            await new AdventureWorksContext((dbNameCli, ProviderType.Sql, clientProvider), true, false).Database.EnsureCreatedAsync();

            var scopeName   = "scopesnap1";
            var syncOptions = new SyncOptions
            {
                BatchSize = 100
            };

            var setup = new SyncSetup();

            // Make a first sync to be sure everything is in place
            var agent = new SyncAgent(clientProvider, serverProvider, syncOptions, this.Tables, scopeName);

            // Making a first sync, will initialize everything we need
            var s = await agent.SynchronizeAsync();

            // Get the orchestrators
            var localOrchestrator  = agent.LocalOrchestrator;
            var remoteOrchestrator = agent.RemoteOrchestrator;

            // Client side : Create a product category and a product
            // Create a productcategory item
            // Create a new product on server
            using (var ctx = new AdventureWorksContext((dbNameCli, ProviderType.Sql, clientProvider)))
            {
                for (int i = 0; i <= 10000; i++)
                {
                    var productId     = Guid.NewGuid();
                    var productName   = HelperDatabase.GetRandomName();
                    var productNumber = productName.ToUpperInvariant().Substring(0, 10);

                    var productCategoryName = HelperDatabase.GetRandomName();
                    var productCategoryId   = productCategoryName.ToUpperInvariant().Substring(0, 6);

                    var pc = new ProductCategory {
                        ProductCategoryId = productCategoryId, Name = productCategoryName
                    };
                    ctx.Add(pc);

                    var product = new Product {
                        ProductId = productId, Name = productName, ProductNumber = productNumber
                    };
                    ctx.Add(product);
                }
                await ctx.SaveChangesAsync();
            }
            var onDatabaseSelecting = 0;
            var onDatabaseSelected  = 0;
            var onSelecting         = 0;
            var onSelected          = 0;

            localOrchestrator.OnDatabaseChangesSelecting(dcs =>
            {
                onDatabaseSelecting++;
            });

            localOrchestrator.OnDatabaseChangesSelected(dcs =>
            {
                Assert.NotNull(dcs.BatchInfo);
                Assert.Equal(2, dcs.ChangesSelected.TableChangesSelected.Count);
                onDatabaseSelected++;
            });

            localOrchestrator.OnTableChangesSelecting(action =>
            {
                Assert.NotNull(action.Command);
                onSelecting++;
            });

            localOrchestrator.OnTableChangesSelected(action =>
            {
                Assert.NotNull(action.Changes);
                onSelected++;
            });

            // Get changes to be populated to the server
            var changes = await localOrchestrator.GetChangesAsync();

            Assert.Equal(this.Tables.Length, onSelecting);
            Assert.Equal(55, onSelected);
            Assert.Equal(1, onDatabaseSelected);
            Assert.Equal(1, onDatabaseSelecting);

            HelperDatabase.DropDatabase(ProviderType.Sql, dbNameSrv);
            HelperDatabase.DropDatabase(ProviderType.Sql, dbNameCli);
        }
Пример #10
0
        public async Task BaseOrchestrator_Provision_Check_Interceptors()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            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 scopeName = "scope";

            var options = new SyncOptions();

            // Options set here and we must check if TableBuilder has correct version
            options.UseBulkOperations = true;

            var setup = new SyncSetup(new string[] { "SalesLT.Product" });

            var onTableProvisioned     = false;
            var onTableProvisioning    = false;
            var onDatabaseProvisioned  = false;
            var onDatabaseProvisioning = false;

            var provision = SyncProvision.Table | SyncProvision.TrackingTable | SyncProvision.StoredProcedures | SyncProvision.Triggers;

            var localOrchestrator = new LocalOrchestrator(sqlProvider, options, setup, scopeName);

            // Assuming GetSchemaAsync() is correct
            // make the GetSchema call, before registrating interceptors
            var schema = await localOrchestrator.GetSchemaAsync();


            localOrchestrator.OnDatabaseProvisioning(args =>
            {
                Assert.IsType <DatabaseProvisioningArgs>(args);
                Assert.Equal(SyncStage.Provisioning, args.Context.SyncStage);
                Assert.Equal(scopeName, args.Context.ScopeName);
                Assert.NotNull(args.Connection);
                Assert.NotNull(args.Transaction);
                Assert.Equal(ConnectionState.Open, args.Connection.State);
                Assert.Equal(provision, args.Provision);
                Assert.Equal(schema, args.Schema);

                onDatabaseProvisioning = true;
            });

            localOrchestrator.OnDatabaseProvisioned(args =>
            {
                Assert.IsType <DatabaseProvisionedArgs>(args);
                Assert.Equal(SyncStage.Provisioned, args.Context.SyncStage);
                Assert.Equal(scopeName, args.Context.ScopeName);
                Assert.NotNull(args.Connection);
                Assert.Null(args.Transaction);
                Assert.Equal(ConnectionState.Closed, args.Connection.State);
                Assert.Equal(provision, args.Provision);
                Assert.Equal(schema, args.Schema);

                onDatabaseProvisioned = true;
            });

            localOrchestrator.OnTableProvisioning(args =>
            {
                Assert.IsType <TableProvisioningArgs>(args);
                Assert.Equal(SyncStage.Provisioning, args.Context.SyncStage);
                Assert.Equal(scopeName, args.Context.ScopeName);
                Assert.NotNull(args.Connection);
                Assert.NotNull(args.Transaction);
                Assert.Equal(ConnectionState.Open, args.Connection.State);
                Assert.True(args.TableBuilder.UseBulkProcedures);
                Assert.False(args.TableBuilder.UseChangeTracking);
                Assert.NotNull(args.TableBuilder.TableDescription);
                Assert.Equal("SalesLT.Product", args.TableBuilder.TableDescription.GetFullName());

                onTableProvisioning = true;
            });
            localOrchestrator.OnTableProvisioned(args =>
            {
                Assert.IsType <TableProvisionedArgs>(args);

                // We are still provisioning the tables
                Assert.Equal(SyncStage.Provisioning, args.Context.SyncStage);
                Assert.Equal(scopeName, args.Context.ScopeName);
                Assert.NotNull(args.Connection);
                Assert.NotNull(args.Transaction);
                Assert.Equal(ConnectionState.Open, args.Connection.State);
                Assert.NotNull(args.SchemaTable);
                Assert.Equal("SalesLT.Product", args.SchemaTable.GetFullName());

                onTableProvisioned = true;
            });

            AssertConnectionAndTransaction(localOrchestrator, SyncStage.Provisioning, SyncStage.Provisioned);

            await localOrchestrator.ProvisionAsync(schema, provision);

            Assert.Equal(SyncStage.Provisioned, localOrchestrator.GetContext().SyncStage);

            Assert.True(onTableProvisioned);
            Assert.True(onTableProvisioning);
            Assert.True(onDatabaseProvisioned);
            Assert.True(onDatabaseProvisioning);

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
Пример #11
0
        public async Task StoredProcedure_Create_All_Overwrite()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true);

            var cs          = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName);
            var sqlProvider = new SqlSyncProvider(cs);

            // Create default table
            var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, sqlProvider), true, false);
            await ctx.Database.EnsureCreatedAsync();

            var options = new SyncOptions();
            var setup   = new SyncSetup(new string[] { "SalesLT.Product" });

            var localOrchestrator = new LocalOrchestrator(sqlProvider, options, setup);

            var onCreating = 0;
            var onCreated  = 0;
            var onDropping = 0;
            var onDropped  = 0;

            localOrchestrator.OnStoredProcedureCreating(tca => onCreating++);
            localOrchestrator.OnStoredProcedureCreated(tca => onCreated++);
            localOrchestrator.OnStoredProcedureDropping(tca => onDropping++);
            localOrchestrator.OnStoredProcedureDropped(tca => onDropped++);

            var isCreated = await localOrchestrator.CreateStoredProceduresAsync(setup.Tables["Product", "SalesLT"]);

            Assert.True(isCreated);
            Assert.Equal(10, onCreating);
            Assert.Equal(10, onCreated);
            Assert.Equal(0, onDropping);
            Assert.Equal(0, onDropped);

            onCreating = 0;
            onCreated  = 0;
            onDropping = 0;
            onDropped  = 0;

            isCreated = await localOrchestrator.CreateStoredProceduresAsync(setup.Tables["Product", "SalesLT"]);

            Assert.False(isCreated);
            Assert.Equal(0, onCreating);
            Assert.Equal(0, onCreated);
            Assert.Equal(0, onDropping);
            Assert.Equal(0, onDropped);

            onCreating = 0;
            onCreated  = 0;
            onDropping = 0;
            onDropped  = 0;

            isCreated = await localOrchestrator.CreateStoredProceduresAsync(setup.Tables["Product", "SalesLT"], true);

            Assert.True(isCreated);
            Assert.Equal(10, onCreating);
            Assert.Equal(10, onCreated);
            Assert.Equal(10, onDropping);
            Assert.Equal(10, onDropped);

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
Пример #12
0
        public async Task StoredProcedure_Create_All()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true);

            var cs          = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName);
            var sqlProvider = new SqlSyncProvider(cs);

            // Create default table
            var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, sqlProvider), true, false);
            await ctx.Database.EnsureCreatedAsync();

            var options = new SyncOptions();
            var setup   = new SyncSetup(new string[] { "SalesLT.Product" });

            var localOrchestrator = new LocalOrchestrator(sqlProvider, options, setup);

            var onCreating = 0;
            var onCreated  = 0;
            var onDropping = 0;
            var onDropped  = 0;

            localOrchestrator.OnStoredProcedureCreating(tca => onCreating++);
            localOrchestrator.OnStoredProcedureCreated(tca => onCreated++);
            localOrchestrator.OnStoredProcedureDropping(tca => onDropping++);
            localOrchestrator.OnStoredProcedureDropped(tca => onDropped++);

            var isCreated = await localOrchestrator.CreateStoredProceduresAsync(setup.Tables["Product", "SalesLT"]);

            Assert.True(isCreated);
            Assert.Equal(10, onCreating);
            Assert.Equal(10, onCreated);
            Assert.Equal(0, onDropping);
            Assert.Equal(0, onDropped);

            // Check
            using (var c = new SqlConnection(cs))
            {
                await c.OpenAsync().ConfigureAwait(false);

                var check = await SqlManagementUtils.ProcedureExistsAsync(c, null, "SalesLT.Product_bulkdelete").ConfigureAwait(false);

                Assert.True(check);
                check = await SqlManagementUtils.ProcedureExistsAsync(c, null, "SalesLT.Product_bulkupdate").ConfigureAwait(false);

                Assert.True(check);
                check = await SqlManagementUtils.ProcedureExistsAsync(c, null, "SalesLT.Product_changes").ConfigureAwait(false);

                Assert.True(check);
                check = await SqlManagementUtils.ProcedureExistsAsync(c, null, "SalesLT.Product_delete").ConfigureAwait(false);

                Assert.True(check);
                check = await SqlManagementUtils.ProcedureExistsAsync(c, null, "SalesLT.Product_deletemetadata").ConfigureAwait(false);

                Assert.True(check);
                check = await SqlManagementUtils.ProcedureExistsAsync(c, null, "SalesLT.Product_initialize").ConfigureAwait(false);

                Assert.True(check);
                check = await SqlManagementUtils.ProcedureExistsAsync(c, null, "SalesLT.Product_reset").ConfigureAwait(false);

                Assert.True(check);
                check = await SqlManagementUtils.ProcedureExistsAsync(c, null, "SalesLT.Product_selectrow").ConfigureAwait(false);

                Assert.True(check);
                check = await SqlManagementUtils.ProcedureExistsAsync(c, null, "SalesLT.Product_update").ConfigureAwait(false);

                Assert.True(check);
                c.Close();
            }


            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
Пример #13
0
        public async Task LocalOrchestrator_Scope()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            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 scopeName = "scope";

            var options = new SyncOptions();
            var setup   = new SyncSetup(this.Tables);

            var localOrchestrator = new LocalOrchestrator(sqlProvider, options);


            var scopeTableCreating = 0;
            var scopeTableCreated  = 0;
            var scopeLoading       = 0;
            var scopeLoaded        = 0;
            var scopeSaving        = 0;
            var scopeSaved         = 0;

            localOrchestrator.OnScopeSaving(ssa =>
            {
                Assert.NotNull(ssa.Command);
                scopeSaving++;
            });

            localOrchestrator.OnScopeSaved(ssa => scopeSaved++);

            localOrchestrator.OnScopeTableCreating(stca =>
            {
                Assert.NotNull(stca.Command);
                scopeTableCreating++;
            });

            localOrchestrator.OnScopeTableCreated(stca =>
            {
                scopeTableCreated++;
            });

            localOrchestrator.OnClientScopeInfoLoading(args =>
            {
                Assert.NotNull(args.Command);
                Assert.Equal(SyncStage.ScopeLoading, args.Context.SyncStage);
                Assert.Equal(scopeName, args.Context.ScopeName);
                Assert.Equal(scopeName, args.ScopeName);
                Assert.NotNull(args.Connection);
                Assert.NotNull(args.Transaction);
                Assert.Equal(ConnectionState.Open, args.Connection.State);
                scopeLoading++;
            });

            localOrchestrator.OnClientScopeInfoLoaded(args =>
            {
                Assert.Equal(SyncStage.ScopeLoading, args.Context.SyncStage);
                Assert.Equal(scopeName, args.Context.ScopeName);
                Assert.NotNull(args.Connection);
                Assert.NotNull(args.Transaction);
                scopeLoaded++;
            });

            var localScopeInfo = await localOrchestrator.GetClientScopeInfoAsync(scopeName);


            Assert.Equal(1, scopeTableCreating);
            Assert.Equal(1, scopeTableCreated);
            Assert.Equal(1, scopeLoading);
            Assert.Equal(1, scopeLoaded);
            Assert.Equal(1, scopeSaving);
            Assert.Equal(1, scopeSaved);

            scopeTableCreating = 0;
            scopeTableCreated  = 0;
            scopeLoading       = 0;
            scopeLoaded        = 0;
            scopeSaving        = 0;
            scopeSaved         = 0;

            localScopeInfo.Version = "2.0";

            await localOrchestrator.SaveClientScopeInfoAsync(localScopeInfo);

            Assert.Equal(0, scopeTableCreating);
            Assert.Equal(0, scopeTableCreated);
            Assert.Equal(0, scopeLoading);
            Assert.Equal(0, scopeLoaded);
            Assert.Equal(1, scopeSaving);
            Assert.Equal(1, scopeSaved);

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
        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);
        }
        public async Task RemoteOrchestrator_CreateSnapshot_CheckInterceptors()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            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, true);
            await ctx.Database.EnsureCreatedAsync();

            var scopeName          = "scopesnap1";
            var onSnapshotCreating = false;
            var onSnapshotCreated  = false;


            // snapshot directory
            var snapshotDirctoryName = HelperDatabase.GetRandomName();
            var snapshotDirectory    = Path.Combine(Environment.CurrentDirectory, snapshotDirctoryName);

            var options = new SyncOptions
            {
                SnapshotsDirectory = snapshotDirectory,
                BatchSize          = 200
            };

            var setup    = new SyncSetup(Tables);
            var provider = new SqlSyncProvider(cs);

            var orchestrator = new RemoteOrchestrator(provider, options, setup, scopeName);

            // Assert on connection and transaction interceptors
            BaseOrchestratorTests.AssertConnectionAndTransaction(orchestrator, SyncStage.SnapshotCreating, SyncStage.SnapshotCreated);

            orchestrator.OnSnapshotCreating(args =>
            {
                Assert.IsType <SnapshotCreatingArgs>(args);
                Assert.Equal(SyncStage.SnapshotCreating, args.Context.SyncStage);
                Assert.Equal(scopeName, args.Context.ScopeName);
                Assert.NotNull(args.Connection);
                Assert.NotNull(args.Transaction);
                Assert.Equal(ConnectionState.Open, args.Connection.State);
                Assert.NotNull(args.Schema);
                Assert.Equal(snapshotDirectory, args.SnapshotDirectory);
                Assert.NotEqual(0, args.Timestamp);

                onSnapshotCreating = true;
            });
            orchestrator.OnSnapshotCreated(args =>
            {
                Assert.IsType <SnapshotCreatedArgs>(args);
                Assert.Equal(SyncStage.SnapshotCreated, args.Context.SyncStage);
                Assert.Equal(scopeName, args.Context.ScopeName);
                Assert.NotNull(args.Connection);
                Assert.Null(args.Transaction);
                Assert.Equal(ConnectionState.Closed, args.Connection.State);
                Assert.NotNull(args.Schema);
                Assert.NotNull(args.BatchInfo);

                var finalDirectoryFullName = Path.Combine(snapshotDirectory, scopeName);

                Assert.Equal(finalDirectoryFullName, args.BatchInfo.DirectoryRoot);
                Assert.Equal("ALL", args.BatchInfo.DirectoryName);
                Assert.Single(args.BatchInfo.BatchPartsInfo);
                Assert.Equal(17, args.BatchInfo.BatchPartsInfo[0].Tables.Length);
                Assert.True(args.BatchInfo.BatchPartsInfo[0].IsLastBatch);

                onSnapshotCreated = true;
            });


            var bi = await orchestrator.CreateSnapshotAsync();

            Assert.Equal(SyncStage.SnapshotCreated, orchestrator.GetContext().SyncStage);

            Assert.True(onSnapshotCreating);
            Assert.True(onSnapshotCreated);

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
Пример #16
0
        public async Task Table_Create_One_Overwrite()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true);

            var cs          = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName);
            var sqlProvider = new SqlSyncProvider(cs);

            var options = new SyncOptions();
            var setup   = new SyncSetup(new string[] { "SalesLT.Product" });

            // Overwrite existing table with this new one
            var table   = new SyncTable("Product", "SalesLT");
            var colID   = new SyncColumn("ID", typeof(Guid));
            var colName = new SyncColumn("Name", typeof(string));

            table.Columns.Add(colID);
            table.Columns.Add(colName);
            table.Columns.Add("Number", typeof(int));
            table.PrimaryKeys.Add("ID");

            var localOrchestrator = new LocalOrchestrator(sqlProvider, options, setup);

            // Call create a first time to have an existing table
            var isCreated = await localOrchestrator.CreateTableAsync(table);

            // Ensuring we have a clean new instance
            localOrchestrator = new LocalOrchestrator(sqlProvider, options, setup);

            var onCreating = false;
            var onCreated  = false;
            var onDropping = false;
            var onDropped  = false;

            localOrchestrator.OnTableCreating(ttca => onCreating = true);
            localOrchestrator.OnTableCreated(ttca => onCreated   = true);
            localOrchestrator.OnTableDropping(ttca => onDropping = true);
            localOrchestrator.OnTableDropped(ttca => onDropped   = true);

            isCreated = await localOrchestrator.CreateTableAsync(table);

            Assert.False(isCreated);
            Assert.False(onDropping);
            Assert.False(onDropped);
            Assert.False(onCreating);
            Assert.False(onCreated);

            onCreating = false;
            onCreated  = false;
            onDropping = false;
            onDropped  = false;

            isCreated = await localOrchestrator.CreateTableAsync(table, true);

            Assert.True(isCreated);
            Assert.True(onDropping);
            Assert.True(onDropped);
            Assert.True(onCreating);
            Assert.True(onCreated);

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
        public async Task RemoteOrchestrator_Trigger_ShouldCreate()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true);

            var cs          = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName);
            var sqlProvider = new SqlSyncProvider(cs);

            // Create default table
            var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, sqlProvider), true, false);
            await ctx.Database.EnsureCreatedAsync();

            var scopeName = "scope";

            var options = new SyncOptions();
            var setup   = new SyncSetup(new string[] { "SalesLT.Product" })
            {
                TriggersPrefix = "trg_",
                TriggersSuffix = "_trg"
            };

            var remoteOrchestrator = new RemoteOrchestrator(sqlProvider, options);
            var scopeInfo          = await remoteOrchestrator.GetServerScopeInfoAsync(scopeName, setup);

            var triggerInsert = $"{setup.TriggersPrefix}Product{setup.TriggersSuffix}_insert_trigger";
            await remoteOrchestrator.CreateTriggerAsync(scopeInfo, "Product", "SalesLT", DbTriggerType.Insert, false);

            using (var c = new SqlConnection(cs))
            {
                await c.OpenAsync().ConfigureAwait(false);

                var trigIns = await SqlManagementUtils.GetTriggerAsync(c, null, triggerInsert, "SalesLT");

                Assert.Equal(triggerInsert, trigIns.Rows[0]["Name"].ToString());

                c.Close();
            }

            var triggerUpdate = $"{setup.TriggersPrefix}Product{setup.TriggersSuffix}_update_trigger";
            await remoteOrchestrator.CreateTriggerAsync(scopeInfo, "Product", "SalesLT", DbTriggerType.Update, false);

            using (var c = new SqlConnection(cs))
            {
                await c.OpenAsync().ConfigureAwait(false);

                var trig = await SqlManagementUtils.GetTriggerAsync(c, null, triggerUpdate, "SalesLT");

                Assert.Equal(triggerUpdate, trig.Rows[0]["Name"].ToString());

                c.Close();
            }

            var triggerDelete = $"{setup.TriggersPrefix}Product{setup.TriggersSuffix}_delete_trigger";
            await remoteOrchestrator.CreateTriggerAsync(scopeInfo, "Product", "SalesLT", DbTriggerType.Delete, false);

            using (var c = new SqlConnection(cs))
            {
                await c.OpenAsync().ConfigureAwait(false);

                var trig = await SqlManagementUtils.GetTriggerAsync(c, null, triggerDelete, "SalesLT");

                Assert.Equal(triggerDelete, trig.Rows[0]["Name"].ToString());

                c.Close();
            }

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
Пример #18
0
        public async Task Table_Drop_One()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true);

            var cs          = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName);
            var sqlProvider = new SqlSyncProvider(cs);

            var options = new SyncOptions();
            var setup   = new SyncSetup(new string[] { "SalesLT.Product" });

            // Overwrite existing table with this new one
            var table   = new SyncTable("Product", "SalesLT");
            var colID   = new SyncColumn("ID", typeof(Guid));
            var colName = new SyncColumn("Name", typeof(string));

            table.Columns.Add(colID);
            table.Columns.Add(colName);
            table.Columns.Add("Number", typeof(int));
            table.PrimaryKeys.Add("ID");

            var localOrchestrator = new LocalOrchestrator(sqlProvider, options, setup);

            // Call create a first time to have an existing table
            var isCreated = await localOrchestrator.CreateTableAsync(table);

            Assert.True(isCreated);

            // Ensuring we have a clean new instance
            localOrchestrator = new LocalOrchestrator(sqlProvider, options, setup);

            var onCreating = false;
            var onCreated  = false;
            var onDropping = false;
            var onDropped  = false;

            localOrchestrator.OnTableCreating(ttca => onCreating = true);
            localOrchestrator.OnTableCreated(ttca => onCreated   = true);
            localOrchestrator.OnTableDropping(ttca => onDropping = true);
            localOrchestrator.OnTableDropped(ttca => onDropped   = true);

            var isDropped = await localOrchestrator.DropTableAsync(setup.Tables[0]);

            Assert.True(isDropped);
            Assert.True(onDropping);
            Assert.True(onDropped);
            Assert.False(onCreating);
            Assert.False(onCreated);

            // Check we have the correct table ovewritten
            using (var c = new SqlConnection(cs))
            {
                await c.OpenAsync().ConfigureAwait(false);

                var stable = await SqlManagementUtils.GetTableAsync(c, null, "Product", "SalesLT").ConfigureAwait(false);

                Assert.Empty(stable.Rows);
                c.Close();
            }

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }
Пример #19
0
        public async Task StoredProcedure_Drop_One_Cancel()
        {
            var dbName = HelperDatabase.GetRandomName("tcp_lo_");
            await HelperDatabase.CreateDatabaseAsync(ProviderType.Sql, dbName, true);

            var cs          = HelperDatabase.GetConnectionString(ProviderType.Sql, dbName);
            var sqlProvider = new SqlSyncProvider(cs);

            // Create default table
            var ctx = new AdventureWorksContext((dbName, ProviderType.Sql, sqlProvider), true, false);
            await ctx.Database.EnsureCreatedAsync();

            var options = new SyncOptions();
            var setup   = new SyncSetup(new string[] { "SalesLT.Product" });

            var remoteOrchestrator = new RemoteOrchestrator(sqlProvider, options);

            var scopeInfo = await remoteOrchestrator.GetServerScopeInfoAsync(setup);

            var isCreated = await remoteOrchestrator.CreateStoredProcedureAsync(scopeInfo, "Product", "SalesLT", DbStoredProcedureType.SelectChanges);

            Assert.True(isCreated);

            // Ensuring we have a clean new instance
            remoteOrchestrator = new RemoteOrchestrator(sqlProvider, options);

            var onCreating = 0;
            var onCreated  = 0;
            var onDropping = 0;
            var onDropped  = 0;

            remoteOrchestrator.OnStoredProcedureCreating(tca => onCreating++);

            remoteOrchestrator.OnStoredProcedureCreated(tca => onCreated++);
            remoteOrchestrator.OnStoredProcedureDropping(tca =>
            {
                tca.Cancel = true;
                onDropping++;
            });
            remoteOrchestrator.OnStoredProcedureDropped(tca => onDropped++);

            var isDropped = await remoteOrchestrator.DropStoredProcedureAsync(scopeInfo, "Product", "SalesLT", DbStoredProcedureType.SelectChanges);

            Assert.False(isDropped);
            Assert.Equal(0, onCreating);
            Assert.Equal(0, onCreated);
            Assert.Equal(1, onDropping);
            Assert.Equal(0, onDropped);

            // Check
            using (var c = new SqlConnection(cs))
            {
                await c.OpenAsync().ConfigureAwait(false);

                var check = await SqlManagementUtils.ProcedureExistsAsync(c, null, "SalesLT.Product_changes").ConfigureAwait(false);

                Assert.True(check);
                c.Close();
            }

            HelperDatabase.DropDatabase(ProviderType.Sql, dbName);
        }