Пример #1
0
        internal async Task <HttpMessageSendChangesResponse> GetEstimatedChangesCountAsync(HttpMessageSendChangesRequest httpMessage,
                                                                                           CancellationToken cancellationToken = default, IProgress <ProgressArgs> progress = null)
        {
            // Get context from request message
            var ctx = httpMessage.SyncContext;

            // Set the context coming from the client
            this.SetContext(ctx);

            var changes = await base.GetEstimatedChangesCountAsync(httpMessage.Scope, cancellationToken, progress);


            var changesResponse = new HttpMessageSendChangesResponse(syncContext);

            changesResponse.ServerChangesSelected    = changes.ServerChangesSelected;
            changesResponse.ClientChangesApplied     = new DatabaseChangesApplied();
            changesResponse.ServerStep               = HttpStep.GetMoreChanges;
            changesResponse.ConflictResolutionPolicy = this.Options.ConflictResolutionPolicy;
            changesResponse.Changes               = new ContainerSet();
            changesResponse.BatchIndex            = 0;
            changesResponse.IsLastBatch           = true;
            changesResponse.RemoteClientTimestamp = changes.RemoteClientTimestamp;

            // Get the firt response to send back to client
            return(changesResponse);
        }
Пример #2
0
 public HttpSendingServerChangesArgs(HttpMessageSendChangesResponse response, string host, SessionCache sessionCache, bool isSnapshot)
     : base(response.SyncContext, null, null)
 {
     this.Response     = response;
     this.Host         = host;
     this.SessionCache = sessionCache;
     this.IsSnapshot   = isSnapshot;
 }
Пример #3
0
        public HttpGettingServerChangesResponseArgs(HttpMessageSendChangesResponse response, string host)
            : base(response.SyncContext, null, null)
        {
            this.BatchIndex            = response.BatchIndex;
            this.BatchCount            = response.BatchCount;
            this.IsLastBatch           = response.IsLastBatch;
            this.Changes               = response.Changes;
            this.RemoteClientTimestamp = response.RemoteClientTimestamp;
            this.ServerChangesSelected = response.ServerChangesSelected;
            this.ClientChangesApplied  = response.ClientChangesApplied;

            this.Host = host;
        }
Пример #4
0
        internal async Task <HttpMessageSendChangesResponse> GetSnapshotAsync(HttpMessageSendChangesRequest httpMessage, SessionCache sessionCache,
                                                                              CancellationToken cancellationToken = default, IProgress <ProgressArgs> progress = null)
        {
            // TODO : check Snapshot with version and scopename

            // Check schema.
            // If client has stored the schema, the EnsureScope will not be called on server.
            if (this.Schema == null || !this.Schema.HasTables || !this.Schema.HasColumns)
            {
                var serverScopeInfo = await this.EnsureSchemaAsync(cancellationToken, progress).ConfigureAwait(false);

                this.Schema = serverScopeInfo.Schema;
                this.Schema.EnsureSchema();
            }

            // Get context from request message
            var ctx = httpMessage.SyncContext;

            // Set the context coming from the client
            this.SetContext(ctx);

            // get changes
            var snap = await this.GetSnapshotAsync(this.Schema, cancellationToken, progress).ConfigureAwait(false);

            // if no snapshot, return empty response
            if (snap.ServerBatchInfo == null)
            {
                var changesResponse = new HttpMessageSendChangesResponse(ctx);
                changesResponse.ServerStep            = HttpStep.GetSnapshot;
                changesResponse.BatchIndex            = 0;
                changesResponse.IsLastBatch           = true;
                changesResponse.RemoteClientTimestamp = 0;
                changesResponse.Changes = null;
                return(changesResponse);
            }

            sessionCache.RemoteClientTimestamp = snap.RemoteClientTimestamp;
            sessionCache.ServerBatchInfo       = snap.ServerBatchInfo;

            // Get the firt response to send back to client
            return(await GetChangesResponseAsync(ctx, snap.RemoteClientTimestamp, snap.ServerBatchInfo, null, null, 0));
        }
        /// <summary>
        /// Get changes from
        /// </summary>
        internal async Task <HttpMessageSendChangesResponse> GetSnapshotAsync(
            HttpMessageSendChangesRequest httpMessage, SessionCache sessionCache, CancellationToken cancellationToken)
        {
            // Check schema.
            // If client has stored the schema, the EnsureScope will not be called on server.
            if (this.Schema == null || !this.Schema.HasTables || !this.Schema.HasColumns)
            {
                var(_, newSchema) = await this.EnsureSchemaAsync(
                    httpMessage.SyncContext, this.Setup, cancellationToken).ConfigureAwait(false);

                newSchema.EnsureSchema();
                this.Schema = newSchema;
            }

            // get changes
            var snap = await this.GetSnapshotAsync(httpMessage.SyncContext, httpMessage.Scope, this.Schema,
                                                   this.Options.SnapshotsDirectory, this.Options.BatchDirectory, cancellationToken).ConfigureAwait(false);

            sessionCache.RemoteClientTimestamp = snap.remoteClientTimestamp;
            sessionCache.ServerBatchInfo       = snap.serverBatchInfo;

            // if no snapshot, return empty response
            if (snap.serverBatchInfo == null)
            {
                var changesResponse = new HttpMessageSendChangesResponse(snap.context);
                changesResponse.ServerStep            = HttpStep.GetSnapshot;
                changesResponse.BatchIndex            = 0;
                changesResponse.IsLastBatch           = true;
                changesResponse.RemoteClientTimestamp = snap.remoteClientTimestamp;
                changesResponse.Changes = new ContainerSet();
                return(changesResponse);
            }


            // Get the firt response to send back to client
            return(GetChangesResponse(snap.context, snap.remoteClientTimestamp, snap.serverBatchInfo, null, 0, ConflictResolutionPolicy.ServerWins));
        }
        /// <summary>
        /// Create a response message content based on a requested index in a server batch info
        /// </summary>
        private HttpMessageSendChangesResponse GetChangesResponse(SyncContext syncContext, long remoteClientTimestamp, BatchInfo serverBatchInfo,
                                                                  DatabaseChangesSelected serverChangesSelected, int batchIndexRequested, ConflictResolutionPolicy policy)
        {
            // 1) Create the http message content response
            var changesResponse = new HttpMessageSendChangesResponse(syncContext);

            changesResponse.ChangesSelected          = serverChangesSelected;
            changesResponse.ServerStep               = HttpStep.GetChanges;
            changesResponse.ConflictResolutionPolicy = policy;

            // If nothing to do, just send back
            if (serverBatchInfo.InMemory || serverBatchInfo.BatchPartsInfo.Count == 0)
            {
                if (this.ClientConverter != null && serverBatchInfo.InMemoryData.HasRows)
                {
                    BeforeSerializeRows(serverBatchInfo.InMemoryData, this.ClientConverter);
                }

                changesResponse.Changes               = serverBatchInfo.InMemoryData.GetContainerSet();
                changesResponse.BatchIndex            = 0;
                changesResponse.IsLastBatch           = true;
                changesResponse.RemoteClientTimestamp = remoteClientTimestamp;
                return(changesResponse);
            }

            // Get the batch part index requested
            var batchPartInfo = serverBatchInfo.BatchPartsInfo.First(d => d.Index == batchIndexRequested);

            // if we are not in memory, we set the BI in session, to be able to get it back on next request

            // create the in memory changes set
            var changesSet = new SyncSet(Schema.ScopeName);

            foreach (var table in Schema.Tables)
            {
                DbSyncAdapter.CreateChangesTable(Schema.Tables[table.TableName, table.SchemaName], changesSet);
            }

            batchPartInfo.LoadBatch(changesSet, serverBatchInfo.GetDirectoryFullPath());

            // if client request a conversion on each row, apply the conversion
            if (this.ClientConverter != null && batchPartInfo.Data.HasRows)
            {
                BeforeSerializeRows(batchPartInfo.Data, this.ClientConverter);
            }

            changesResponse.Changes = batchPartInfo.Data.GetContainerSet();

            changesResponse.BatchIndex            = batchIndexRequested;
            changesResponse.IsLastBatch           = batchPartInfo.IsLastBatch;
            changesResponse.RemoteClientTimestamp = remoteClientTimestamp;
            changesResponse.ServerStep            = batchPartInfo.IsLastBatch ? HttpStep.GetChanges : HttpStep.GetChangesInProgress;

            // If we have only one bpi, we can safely delete it
            if (batchPartInfo.IsLastBatch)
            {
                // delete the folder (not the BatchPartInfo, because we have a reference on it)
                if (this.Options.CleanFolder)
                {
                    var shouldDeleteFolder = true;
                    if (!string.IsNullOrEmpty(this.Options.SnapshotsDirectory))
                    {
                        var dirInfo  = new DirectoryInfo(serverBatchInfo.DirectoryRoot);
                        var snapInfo = new DirectoryInfo(this.Options.SnapshotsDirectory);
                        shouldDeleteFolder = dirInfo.FullName != snapInfo.FullName;
                    }

                    if (shouldDeleteFolder)
                    {
                        serverBatchInfo.TryRemoveDirectory();
                    }
                }
            }

            return(changesResponse);
        }