예제 #1
0
    /// <summary>
    /// Launch a simple sync, over TCP network, each sql server (client and server are reachable through TCP cp
    /// </summary>
    /// <returns></returns>
    private static async Task SynchronizeAsync()
    {
        // Create 2 Sql Sync providers
        var serverProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(serverDbName));
        var clientProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(clientDbName));

        // Tables involved in the sync process:
        var tables = allTables;

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

        // Using the Progress pattern to handle progession during the synchronization
        var progress = new Progress <ProgressArgs>(s => Console.WriteLine($"[client]: {s.Context.SyncStage}:\t{s.Message}"));


        // Setting configuration options
        agent.SetConfiguration(s =>
        {
            s.ScopeInfoTableName     = "tscopeinfo";
            s.SerializationFormat    = Dotmim.Sync.Enumerations.SerializationFormat.Binary;
            s.StoredProceduresPrefix = "s";
            s.StoredProceduresSuffix = "";
            s.TrackingTablesPrefix   = "t";
            s.TrackingTablesSuffix   = "";
        });

        agent.SetOptions(opt =>
        {
            opt.BatchDirectory    = Path.Combine(SyncOptions.GetDefaultUserBatchDiretory(), "sync");
            opt.BatchSize         = 100;
            opt.CleanMetadatas    = true;
            opt.UseBulkOperations = true;
            opt.UseVerboseErrors  = false;
        });


        do
        {
            Console.Clear();
            Console.WriteLine("Sync Start");
            try
            {
                // Launch the sync process
                var s1 = await agent.SynchronizeAsync(progress);

                // Write results
                Console.WriteLine(s1);
            }
            catch (Exception e)
            {
                Console.WriteLine(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");
    }
예제 #2
0
    /// <summary>
    /// Launch a simple sync, over TCP network, each sql server (client and server are reachable through TCP cp
    /// </summary>
    /// <returns></returns>
    private static async Task SynchronizeExistingTablesAsync()
    {
        string serverName = "ServerTablesExist";
        string clientName = "ClientsTablesExist";

        await DbHelper.EnsureDatabasesAsync(serverName);

        await DbHelper.EnsureDatabasesAsync(clientName);

        // Create 2 Sql Sync providers
        var serverProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(serverName));
        var clientProvider = new SqlSyncProvider(DbHelper.GetDatabaseConnectionString(clientName));

        // Tables involved in the sync process:
        var tables = allTables;

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

        // Using the Progress pattern to handle progession during the synchronization
        var progress = new Progress <ProgressArgs>(s => Console.WriteLine($"[client]: {s.Context.SyncStage}:\t{s.Message}"));



        // Setting configuration options
        agent.SetConfiguration(s =>
        {
            s.ScopeInfoTableName     = "tscopeinfo";
            s.SerializationFormat    = Dotmim.Sync.Enumerations.SerializationFormat.Binary;
            s.StoredProceduresPrefix = "s";
            s.StoredProceduresSuffix = "";
            s.TrackingTablesPrefix   = "t";
            s.TrackingTablesSuffix   = "";
        });

        agent.SetOptions(opt =>
        {
            opt.BatchDirectory    = Path.Combine(SyncOptions.GetDefaultUserBatchDiretory(), "sync");
            opt.BatchSize         = 100;
            opt.CleanMetadatas    = true;
            opt.UseBulkOperations = true;
            opt.UseVerboseErrors  = false;
        });


        var remoteProvider = agent.RemoteProvider as CoreProvider;

        var dpAction = new Action <DatabaseProvisionedArgs>(args =>
        {
            Console.WriteLine($"-- [InterceptDatabaseProvisioned] -- ");

            var sql = $"Update tscopeinfo set scope_last_sync_timestamp = 0 where [scope_is_local] = 1";

            var cmd         = args.Connection.CreateCommand();
            cmd.Transaction = args.Transaction;
            cmd.CommandText = sql;

            cmd.ExecuteNonQuery();
        });

        remoteProvider.InterceptDatabaseProvisioned(dpAction);

        agent.LocalProvider.InterceptDatabaseProvisioned(dpAction);

        do
        {
            Console.Clear();
            Console.WriteLine("Sync Start");
            try
            {
                // Launch the sync process
                var s1 = await agent.SynchronizeAsync(progress);

                // Write results
                Console.WriteLine(s1);
            }
            catch (Exception e)
            {
                Console.WriteLine(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");
    }
예제 #3
0
        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);
        }