Exemple #1
0
        private async void Handle_Clicked(object sender, System.EventArgs e)
        {
            try
            {
                // Use this when you want to use sqlite on ios
                SQLitePCL.Batteries_V2.Init();

                // 10.0.2.2 is a special url to be able to reach the machine localhost web api
                var serverOrchestrator = new WebClientOrchestrator("http://10.0.2.2:50886/api/sync");

                // Path the local sqlite database
                string dbPath = Path.Combine(Xamarin.Essentials.FileSystem.AppDataDirectory, "SqliteDatabase.db3");

                var clientOptions = new SyncOptions {
                    BatchSize = 3000
                };

                // Sqlite Client provider
                var clientProvider = new SqliteSyncProvider(dbPath);

                // Creating an agent that will handle all the process
                var agent = new SyncAgent(clientProvider, serverOrchestrator, clientOptions);

                var progress = new Progress <ProgressArgs>(args => lblProgress.Text = $"{args.Context.SyncStage}:{args.Message}");

                // Launch the sync process
                var s1 = await agent.SynchronizeAsync(progress);

                // See results
                lblResult.Text = s1.ToString();
            }
            catch (Exception ex)
            {
                lblResult.Text = ex.Message;
            }
        }
        public static async Task SynchronizeDefaultAsync(WebClientOrchestrator serverOrchestrator, SqlSyncProvider clientProvider, SyncOptions options, bool reinitialize = false)
        {
            var agent = new SyncAgent(clientProvider, serverOrchestrator, options);

            agent.Parameters.Add("City", "Toronto");
            agent.Parameters.Add("postal", DBNull.Value);
            var syncType = reinitialize ? SyncType.Reinitialize : SyncType.Normal;

            var progress = new SynchronousProgress <ProgressArgs>(
                pa => Console.WriteLine($"{pa.ProgressPercentage:p}\t {pa.Message}"));

            try
            {
                // Launch the sync process
                var s1 = await agent.SynchronizeAsync(syncType, progress);

                // Write results
                Console.WriteLine(s1);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
Exemple #3
0
 /// <summary>
 /// Intercept the provider when an http call to get scope is done
 /// </summary>
 public static void OnHttpGettingScopeResponse(this WebClientOrchestrator orchestrator, Func <HttpGettingScopeResponseArgs, Task> action)
 => orchestrator.SetInterceptor(action);
Exemple #4
0
 /// <summary>
 /// Intercept the provider when an http is about to be done to get server scope
 /// </summary>
 public static void OnHttpGettingScopeRequest(this WebClientOrchestrator orchestrator, Action <HttpGettingScopeRequestArgs> action)
 => orchestrator.SetInterceptor(action);
Exemple #5
0
        private static async Task SynchronizeAsync(CoreProvider clientProvider)
        {
            // Database script used for this sample : https://github.com/Mimetis/Dotmim.Sync/blob/master/CreateAdventureWorks.sql

            var serverOrchestrator = new WebClientOrchestrator("https://localhost:44342/api/sync");


            // Creating an agent that will handle all the process
            var agent = new SyncAgent(clientProvider, serverOrchestrator);

            try
            {
                var progress = new SynchronousProgress <ProgressArgs>(args => Console.WriteLine($"{args.PogressPercentageString}:\t{args.Message}"));

                // Get the client scope
                var scope = await agent.LocalOrchestrator.GetClientScopeAsync();

                if (scope.IsNewScope)
                {
                    var client           = new HttpClient();
                    var seedingsResponse = await client.GetAsync($"https://localhost:44342/api/sync/seedings/{scope.Id}");

                    seedingsResponse.EnsureSuccessStatusCode();

                    var seedingsResponseString = await seedingsResponse.Content.ReadAsStringAsync();

                    var seedings = JsonConvert.DeserializeObject <List <Seeding> >(seedingsResponseString);

                    agent.LocalOrchestrator.OnTableCreating(async tca =>
                    {
                        var tableName  = tca.TableName.Unquoted().ToString();
                        var schemaName = string.IsNullOrEmpty(tca.TableName.SchemaName) ? "dbo" : tca.TableName.SchemaName;

                        var seeding = seedings.FirstOrDefault(s => s.TableName == tableName && s.SchemaName == schemaName);
                        var id      = tca.Table.GetPrimaryKeysColumns().ToList()[0];

                        if (seeding != null && id.IsAutoIncrement)
                        {
                            id.AutoIncrementSeed = seeding.Seed;
                            id.AutoIncrementStep = seeding.Step;
                        }

                        var newTableBuilder = agent.LocalOrchestrator.GetTableBuilder(tca.Table, agent.LocalOrchestrator.Setup);

                        var newCommand = await newTableBuilder.GetCreateTableCommandAsync(tca.Connection, tca.Transaction);

                        tca.Command.CommandText = newCommand.CommandText;
                    });
                }

                // Launch the sync process
                var s1 = await agent.SynchronizeAsync(progress);

                // Write results
                Console.WriteLine(s1);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.WriteLine("End");
        }
Exemple #6
0
 /// <summary>
 /// Intercept the provider when client is trying to send again an http request message
 /// </summary>
 public static void OnHttpPolicyRetrying(this WebClientOrchestrator orchestrator,
                                         Func <HttpSyncPolicyArgs, Task> action)
 => orchestrator.SetInterceptor(action);
 /// <summary>
 /// Intercept the provider when batches are about to be downloaded
 /// </summary>
 public static void OnHttpBatchesDownloadingArgs(this WebClientOrchestrator orchestrator, Action <HttpBatchesDownloadingArgs> action)
 => orchestrator.SetInterceptor(action);
 /// <summary>
 /// Intercept the provider when batches have been completely downloaded
 /// </summary>
 public static void OnHttpBatchesDownloadedArgs(this WebClientOrchestrator orchestrator, Func <HttpBatchesDownloadedArgs, Task> action)
 => orchestrator.SetInterceptor(action);
Exemple #9
0
 /// <summary>
 /// Intercept the provider when a batch changes has been downloaded from server side
 /// </summary>
 public static void OnHttpGettingChangesResponse(this WebClientOrchestrator orchestrator, Action <HttpGettingServerChangesResponseArgs> action)
 => orchestrator.SetInterceptor(action);
Exemple #10
0
 /// <summary>
 /// Intercept the provider when downloading a batch changes from server side.
 /// </summary>
 public static void OnHttpGettingChangesRequest(this WebClientOrchestrator orchestrator, Func <HttpGettingServerChangesRequestArgs, Task> action)
 => orchestrator.SetInterceptor(action);
Exemple #11
0
 /// <summary>
 /// Intercept the provider when batch changes is uploading to server.
 /// </summary>
 public static void OnHttpSendingChangesRequest(this WebClientOrchestrator orchestrator, Action <HttpSendingClientChangesRequestArgs> action)
 => orchestrator.SetInterceptor(action);
        internal SyncContext Sync(string value)
        {
            if (String.IsNullOrEmpty(value))
            {
                throw new Exception("Loading a project requires a name. Ex : dotnet sync --load project01");
            }

            Project project = DataStore.Current.LoadProject(value);

            if (project == null)
            {
                throw new Exception($"Project {value} does not exists.");
            }

            if (project.ServerProvider == null || string.IsNullOrEmpty(project.ServerProvider.ConnectionString))
            {
                throw new Exception($"Server provider for project {project.Name} is not correctly defined. See help: dotnet sync provider --help");
            }

            if (project.ClientProvider == null || string.IsNullOrEmpty(project.ClientProvider.ConnectionString))
            {
                throw new Exception($"Client provider for project {project.Name} is not correctly defined. See help: dotnet sync provider --help");
            }

            if (project.ServerProvider.ProviderType != ProviderType.Web && (project.Tables == null || project.Tables.Count <= 0))
            {
                throw new Exception($"No table configured for project {project.Name}. See help: dotnet sync table --help");
            }

            IRemoteOrchestrator remoteOrchestrator;
            ILocalOrchestrator  localOrchestrator;

            switch (project.ServerProvider.ProviderType)
            {
            case ProviderType.Sqlite:
                throw new Exception("Can't use Sqlite as a server provider");

            case ProviderType.Web:
                remoteOrchestrator = new WebClientOrchestrator(new Uri(project.ServerProvider.ConnectionString));
                break;

            case ProviderType.MySql:
                remoteOrchestrator = new RemoteOrchestrator(new MySqlSyncProvider(project.ServerProvider.ConnectionString));
                break;

            case ProviderType.SqlServer:
            default:
                remoteOrchestrator = new RemoteOrchestrator(new SqlSyncProvider(project.ServerProvider.ConnectionString));
                break;
            }

            switch (project.ClientProvider.ProviderType)
            {
            case ProviderType.Web:
                throw new Exception("Web proxy is used as a proxy server. You have to use an ASP.NET web backend. CLI uses a proxy as server provider");

            case ProviderType.Sqlite:
                localOrchestrator = new LocalOrchestrator(new SqliteSyncProvider(project.ClientProvider.ConnectionString));
                break;

            case ProviderType.MySql:
                localOrchestrator = new LocalOrchestrator(new MySqlSyncProvider(project.ClientProvider.ConnectionString));
                break;

            case ProviderType.SqlServer:
            default:
                localOrchestrator = new LocalOrchestrator(new SqlSyncProvider(project.ClientProvider.ConnectionString));
                break;
            }

            SyncAgent agent = null;

            if (project.ServerProvider.ProviderType != ProviderType.Web)
            {
                agent = new SyncAgent(localOrchestrator, remoteOrchestrator);

                var syncSchema = new SyncSchema();
                //var syncConfiguration = agent.LocalOrchestrator.Configuration;

                foreach (var t in project.Tables.OrderBy(tbl => tbl.Order))
                {
                    // Potentially user can pass something like [SalesLT].[Product]
                    // or SalesLT.Product or Product. ParserName will handle it
                    var parser = ParserName.Parse(t.Name);

                    var tableName = parser.ObjectName;
                    var schema    = string.IsNullOrEmpty(t.Schema) ? parser.SchemaName : t.Schema;

                    var dmTable = new DmTable(tableName);

                    if (!String.IsNullOrEmpty(schema))
                    {
                        dmTable.Schema = schema;
                    }

                    dmTable.SyncDirection = t.Direction;

                    agent.SetSchema(agentSchema => agentSchema.Add(dmTable));
                }

                agent.SetOptions(o => o.BatchDirectory = string.IsNullOrEmpty(project.Configuration.BatchDirectory) ? null : project.Configuration.BatchDirectory);
                agent.SetOptions(o => o.BatchSize      = (int)Math.Min(Int32.MaxValue, project.Configuration.DownloadBatchSizeInKB));
                //agent.SetOptions(o => o.SerializationFormat = project.Configuration.SerializationFormat);

                //agent.Options.UseBulkOperations = project.Configuration.UseBulkOperation;

                agent.SetSchema(agentSchema =>
                {
                    agentSchema.ConflictResolutionPolicy = project.Configuration.ConflictResolutionPolicy;
                });
            }
            else
            {
                agent = new SyncAgent(localOrchestrator, remoteOrchestrator);
            }

            agent.LocalOrchestrator.OnTableChangesSelected(tcs => Console.WriteLine($"Changes selected for table {tcs.TableChangesSelected.TableName}: {tcs.TableChangesSelected.TotalChanges}"));
            agent.LocalOrchestrator.OnTableChangesApplied(tca => Console.WriteLine($"Changes applied for table {tca.TableChangesApplied.Table.TableName}: [{tca.TableChangesApplied.State}] {tca.TableChangesApplied.Applied}"));

            // synchronous call
            var syncContext = agent.SynchronizeAsync().GetAwaiter().GetResult();

            var tsEnded   = TimeSpan.FromTicks(syncContext.CompleteTime.Ticks);
            var tsStarted = TimeSpan.FromTicks(syncContext.StartTime.Ticks);

            var durationTs  = tsEnded.Subtract(tsStarted);
            var durationstr = $"{durationTs.Hours}:{durationTs.Minutes}:{durationTs.Seconds}.{durationTs.Milliseconds}";

            Console.ForegroundColor = ConsoleColor.Green;
            var s = $"Synchronization done. " + Environment.NewLine +
                    $"\tTotal changes downloaded: {syncContext.TotalChangesDownloaded} " + Environment.NewLine +
                    $"\tTotal changes uploaded: {syncContext.TotalChangesUploaded}" + Environment.NewLine +
                    $"\tTotal duration :{durationstr} ";

            Console.WriteLine(s);
            Console.ResetColor();


            return(syncContext);
        }
Exemple #13
0
    /// <summary>
    /// Test a client syncing through a web api
    /// </summary>
    private static async Task SyncThroughWebApiAsync()
    {
        var clientProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(clientDbName));

        var handler = new HttpClientHandler {
            AutomaticDecompression = DecompressionMethods.GZip
        };
        var client = new HttpClient(handler)
        {
            Timeout = TimeSpan.FromMinutes(5)
        };

        var proxyClientProvider = new WebClientOrchestrator("http://localhost:52288/api/Sync", null, null, client);



        // ----------------------------------
        // Client side
        // ----------------------------------
        var clientOptions = new SyncOptions
        {
            ScopeInfoTableName = "client_scopeinfo",
            BatchDirectory     = Path.Combine(SyncOptions.GetDefaultUserBatchDiretory(), "sync_client"),
            BatchSize          = 50,
            CleanMetadatas     = true,
            UseBulkOperations  = true,
            UseVerboseErrors   = false,
        };

        var clientSetup = new SyncSetup
        {
            StoredProceduresPrefix = "cli",
            StoredProceduresSuffix = "",
            TrackingTablesPrefix   = "cli",
            TrackingTablesSuffix   = "",
            TriggersPrefix         = "",
            TriggersSuffix         = "",
        };


        var agent = new SyncAgent(clientProvider, proxyClientProvider, clientSetup, clientOptions);

        Console.WriteLine("Press a key to start (be sure web api is running ...)");
        Console.ReadKey();
        do
        {
            Console.Clear();
            Console.WriteLine("Web sync start");
            try
            {
                var progress = new SynchronousProgress <ProgressArgs>(pa => Console.WriteLine($"{pa.Context.SessionId} - {pa.Context.SyncStage}\t {pa.Message}"));

                var s = await agent.SynchronizeAsync(progress);

                Console.WriteLine(s);
            }
            catch (SyncException e)
            {
                Console.WriteLine(e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine("UNKNOW EXCEPTION : " + e.Message);
            }


            Console.WriteLine("Sync Ended. Press a key to start again, or Escapte to end");
        } while (Console.ReadKey().Key != ConsoleKey.Escape);

        Console.WriteLine("End");
    }
Exemple #14
0
    public static async Task SyncHttpThroughKestellAsync()
    {
        // server provider
        // Create 2 Sql Sync providers
        var serverProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(serverDbName));
        var clientProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(clientDbName));


        // ----------------------------------
        // Client side
        // ----------------------------------
        var clientOptions = new SyncOptions {
            BatchSize = 500
        };

        var proxyClientProvider = new WebClientOrchestrator();

        // ----------------------------------
        // Web Server side
        // ----------------------------------
        var setup = new SyncSetup(allTables)
        {
            ScopeName = "all_tables_scope",
            StoredProceduresPrefix = "s",
            StoredProceduresSuffix = "",
            TrackingTablesPrefix   = "t",
            TrackingTablesSuffix   = "",
            TriggersPrefix         = "",
            TriggersSuffix         = "t"
        };

        // snapshot directory
        var directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Snapshots");

        // ----------------------------------
        // Create a snapshot
        // ----------------------------------
        Console.ForegroundColor = ConsoleColor.Yellow;
        Console.WriteLine($"Creating snapshot");
        var remoteOrchestrator = new RemoteOrchestrator(serverProvider);
        await remoteOrchestrator.CreateSnapshotAsync(new SyncContext(), setup, directory, 500, CancellationToken.None);

        Console.WriteLine($"Done.");
        Console.ResetColor();


        // ----------------------------------
        // Insert a value after snapshot created
        // ----------------------------------
        using (var c = serverProvider.CreateConnection())
        {
            var command = c.CreateCommand();
            command.CommandText = "INSERT INTO [dbo].[ProductCategory] ([Name]) VALUES ('Bikes revolution');";
            c.Open();
            command.ExecuteNonQuery();
            c.Close();
        }

        var webServerOptions = new WebServerOptions {
            SnapshotsDirectory = directory
        };

        // Creating an agent that will handle all the process
        var agent = new SyncAgent(clientProvider, proxyClientProvider);

        agent.Options = clientOptions;

        var configureServices = new Action <IServiceCollection>(services =>
        {
            services.AddSyncServer <SqlSyncProvider>(serverProvider.ConnectionString, setup, webServerOptions);
        });

        var serverHandler = new RequestDelegate(async context =>
        {
            var webProxyServer = context.RequestServices.GetService(typeof(WebProxyServerOrchestrator)) as WebProxyServerOrchestrator;
            await webProxyServer.HandleRequestAsync(context);
        });

        using (var server = new KestrellTestServer(configureServices))
        {
            var clientHandler = new ResponseDelegate(async(serviceUri) =>
            {
                proxyClientProvider.ServiceUri = serviceUri;
                do
                {
                    Console.Clear();
                    Console.WriteLine("Web sync start");
                    try
                    {
                        var progress = new SynchronousProgress <ProgressArgs>(pa => Console.WriteLine($"{pa.Context.SyncStage}\t {pa.Message}"));
                        var s        = await agent.SynchronizeAsync(progress);
                        Console.WriteLine(s);
                    }
                    catch (SyncException e)
                    {
                        Console.WriteLine(e.ToString());
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("UNKNOW EXCEPTION : " + e.Message);
                    }


                    Console.WriteLine("Sync Ended. Press a key to start again, or Escapte to end");
                } while (Console.ReadKey().Key != ConsoleKey.Escape);
            });
            await server.Run(serverHandler, clientHandler);
        }
    }
Exemple #15
0
 /// <summary>
 /// Intercept the provider when an http message response is downloaded from remote side
 /// </summary>
 public static void OnHttpGettingResponse(this WebClientOrchestrator orchestrator,
                                          Action <HttpGettingResponseMessageArgs> action)
 => orchestrator.SetInterceptor(action);
Exemple #16
0
 /// <summary>
 /// Intercept the provider when an http request message is sent
 /// </summary>
 public static void OnHttpSendingRequest(this WebClientOrchestrator orchestrator,
                                         Func <HttpSendingRequestMessageArgs, Task> action)
 => orchestrator.SetInterceptor(action);