Exemplo n.º 1
0
        /// <summary>
        /// Ensure the scope is created on the local provider.
        /// The scope contains all about last sync, schema and scope and local / remote timestamp
        /// </summary>
        public virtual async Task <(SyncContext, ScopeInfo)> EnsureScopesAsync(SyncContext context, string scopeInfoTableName, string scopeName,
                                                                               DbConnection connection, DbTransaction transaction,
                                                                               CancellationToken cancellationToken, IProgress <ProgressArgs> progress = null)
        {
            var scopes = new List <ScopeInfo>();

            var scopeBuilder     = this.GetScopeBuilder();
            var scopeInfoBuilder = scopeBuilder.CreateScopeInfoBuilder(scopeInfoTableName, connection, transaction);

            var needToCreateScopeInfoTable = scopeInfoBuilder.NeedToCreateScopeInfoTable();

            // create the scope info table if needed
            if (needToCreateScopeInfoTable)
            {
                scopeInfoBuilder.CreateScopeInfoTable();
            }

            // not the first time we ensure scopes, so get scopes
            if (!needToCreateScopeInfoTable)
            {
                // get all scopes shared by all (identified by scopeName)
                scopes = scopeInfoBuilder.GetAllScopes(scopeName);
            }

            // If no scope found, create it on the local provider
            if (scopes == null || scopes.Count <= 0)
            {
                scopes = new List <ScopeInfo>();

                // create a new scope id for the current owner (could be server or client as well)
                var scope = new ScopeInfo
                {
                    Id         = Guid.NewGuid(),
                    Name       = scopeName,
                    IsNewScope = true,
                    LastSync   = null,
                };

                scope = scopeInfoBuilder.InsertOrUpdateScopeInfo(scope);
                scopes.Add(scope);
            }
            else
            {
                //check if we have alread a good last sync. if no, treat it as new
                scopes.ForEach(sc => sc.IsNewScope = sc.LastSync == null);
            }

            // get first scope
            var localScope = scopes.FirstOrDefault();

            // Progress & Interceptor
            context.SyncStage = SyncStage.ScopeLoading;
            var scopeArgs = new ScopeArgs(context, localScope, connection, transaction);

            this.ReportProgress(context, progress, scopeArgs);
            await this.InterceptAsync(scopeArgs).ConfigureAwait(false);

            return(context, localScope);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Write scope in the provider datasource
        /// </summary>
        public virtual async Task <SyncContext> WriteScopesAsync(SyncContext context,
                                                                 MessageWriteScopes message)
        {
            DbConnection  connection  = null;
            DbTransaction transaction = null;

            try
            {
                // Open the connection
                using (connection = this.CreateConnection())
                {
                    await connection.OpenAsync();

                    await this.InterceptAsync(new ConnectionOpenArgs(context, connection));

                    using (transaction = connection.BeginTransaction())
                    {
                        await this.InterceptAsync(new TransactionOpenArgs(context, connection, transaction));

                        var scopeBuilder     = this.GetScopeBuilder();
                        var scopeInfoBuilder = scopeBuilder.CreateScopeInfoBuilder(message.ScopeInfoTableName, connection, transaction);

                        var lstScopes = new List <ScopeInfo>();

                        foreach (var scope in message.Scopes)
                        {
                            lstScopes.Add(scopeInfoBuilder.InsertOrUpdateScopeInfo(scope));
                        }

                        // Progress & Interceptor
                        context.SyncStage = SyncStage.ScopeSaved;
                        var scopeArgs = new ScopeArgs(context, lstScopes.FirstOrDefault(s => s.IsLocal), connection, transaction);
                        this.ReportProgress(context, scopeArgs);
                        await this.InterceptAsync(scopeArgs);

                        await this.InterceptAsync(new TransactionCommitArgs(context, connection, transaction));

                        transaction.Commit();
                    }

                    connection.Close();
                }
            }
            catch (Exception ex)
            {
                throw new SyncException(ex, SyncStage.ScopeSaved);
            }
            finally
            {
                if (connection != null && connection.State != ConnectionState.Closed)
                {
                    connection.Close();
                }

                await this.InterceptAsync(new ConnectionCloseArgs(context, connection, transaction));
            }
            return(context);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Write scope in the local data source
        /// </summary>
        public virtual async Task <SyncContext> WriteScopesAsync(SyncContext context, string scopeInfoTableName, ScopeInfo scope,
                                                                 DbConnection connection, DbTransaction transaction,
                                                                 CancellationToken cancellationToken, IProgress <ProgressArgs> progress = null)
        {
            var scopeBuilder     = this.GetScopeBuilder();
            var scopeInfoBuilder = scopeBuilder.CreateScopeInfoBuilder(scopeInfoTableName, connection, transaction);

            scopeInfoBuilder.InsertOrUpdateScopeInfo(scope);

            // Progress & Interceptor
            context.SyncStage = SyncStage.ScopeSaved;
            var scopeArgs = new ScopeArgs(context, scope, connection, transaction);

            this.ReportProgress(context, progress, scopeArgs);
            await this.InterceptAsync(scopeArgs).ConfigureAwait(false);

            return(context);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Called when the sync ensure scopes are created
        /// </summary>
        public virtual async Task <(SyncContext, List <ScopeInfo>)> EnsureScopesAsync(SyncContext context, MessageEnsureScopes message)
        {
            DbConnection connection = null;

            try
            {
                var scopes = new List <ScopeInfo>();

                // Open the connection
                using (connection = this.CreateConnection())
                {
                    await connection.OpenAsync();

                    using (var transaction = connection.BeginTransaction())
                    {
                        var scopeBuilder     = this.GetScopeBuilder();
                        var scopeInfoBuilder = scopeBuilder.CreateScopeInfoBuilder(
                            message.ScopeInfoTableName, connection, transaction);

                        var needToCreateScopeInfoTable = scopeInfoBuilder.NeedToCreateScopeInfoTable();

                        // create the scope info table if needed
                        if (needToCreateScopeInfoTable)
                        {
                            scopeInfoBuilder.CreateScopeInfoTable();
                        }

                        // not the first time we ensure scopes, so get scopes
                        if (!needToCreateScopeInfoTable)
                        {
                            // get all scopes shared by all (identified by scopeName)
                            var lstScopes = scopeInfoBuilder.GetAllScopes(message.ScopeName);

                            // try to get the scopes from database
                            // could be two scopes if from server or a single scope if from client
                            scopes = lstScopes.Where(s => (s.IsLocal == true || (message.ClientReferenceId.HasValue && s.Id == message.ClientReferenceId.Value))).ToList();
                        }

                        // If no scope found, create it on the local provider
                        if (scopes == null || scopes.Count <= 0)
                        {
                            scopes = new List <ScopeInfo>();

                            // create a new scope id for the current owner (could be server or client as well)
                            var scope = new ScopeInfo
                            {
                                Id         = Guid.NewGuid(),
                                Name       = message.ScopeName,
                                IsLocal    = true,
                                IsNewScope = true,
                                LastSync   = null
                            };

                            scope = scopeInfoBuilder.InsertOrUpdateScopeInfo(scope);

                            scopes.Add(scope);
                        }
                        else
                        {
                            //check if we have alread a good last sync. if no, treat it as new
                            scopes.ForEach(sc => sc.IsNewScope = sc.LastSync == null);
                        }

                        // if we are not on the server, we have to check that we only have one scope
                        if (!message.ClientReferenceId.HasValue && scopes.Count > 1)
                        {
                            throw new InvalidOperationException("On Local provider, we should have only one scope info");
                        }


                        // if we have a reference in args, we need to get this specific line from database
                        // this happen only on the server side
                        if (message.ClientReferenceId.HasValue)
                        {
                            var refScope = scopes.FirstOrDefault(s => s.Id == message.ClientReferenceId);

                            if (refScope == null)
                            {
                                refScope = new ScopeInfo
                                {
                                    Id         = message.ClientReferenceId.Value,
                                    Name       = message.ScopeName,
                                    IsLocal    = false,
                                    IsNewScope = true,
                                    LastSync   = null
                                };

                                refScope = scopeInfoBuilder.InsertOrUpdateScopeInfo(refScope);

                                scopes.Add(refScope);
                            }
                            else
                            {
                                refScope.IsNewScope = refScope.LastSync == null;
                            }
                        }

                        // Progress & Interceptor
                        context.SyncStage = SyncStage.ScopeLoading;
                        var scopeArgs = new ScopeArgs(context, scopes.FirstOrDefault(s => s.IsLocal), connection, transaction);
                        this.ReportProgress(context, scopeArgs);
                        await this.InterceptAsync(scopeArgs);

                        transaction.Commit();
                    }

                    connection.Close();
                }

                return(context, scopes);
            }
            catch (Exception ex)
            {
                throw new SyncException(ex, SyncStage.ScopeLoading);
            }
            finally
            {
                if (connection != null && connection.State != ConnectionState.Closed)
                {
                    connection.Close();
                }
            }
        }