Exemple #1
0
        internal void ApplyChanges(ApplyChangesParameter parameter, ref ApplyChangesResult result)
        {
            if (parameter == null)
            {
                throw new NullReferenceException(nameof(parameter));
            }
            result = new ApplyChangesResult(parameter.PayloadAction, parameter.SynchronizationId, parameter.CustomInfo);

            parameter.Log.Add("Applying Data Type Changes...");
            parameter.Log.Add($"SyncTypes Count: {parameter.Changes.Count}");
            List <Type> postEventTypes = new List <Type>();
            Dictionary <Type, List <object> > dictDeletedIds = new Dictionary <Type, List <object> >();

            for (int i = 0; i < parameter.Changes.Count; i++)
            {
                JObject typeChanges = parameter.Changes[i].Value <JObject>();
                parameter.Log.Add($"Applying Type: {typeChanges["syncType"].Value<string>()}...");
                (Type localSyncType, List <object> appliedIds, List <object> deletedIds) = ApplyTypeChanges(parameter.Log, result.Inserts, result.Updates, result.Deletes, result.Conflicts, typeChanges, parameter.SynchronizationId, parameter.CustomInfo, null, null);
                parameter.Log.Add($"Type: {typeChanges["syncType"].Value<string>()} Applied, Count: {appliedIds.Count}");
                result.AppliedIds[localSyncType] = appliedIds;
                if (deletedIds.Count > 0)
                {
                    if (!postEventTypes.Contains(localSyncType))
                    {
                        postEventTypes.Add(localSyncType);
                    }
                    dictDeletedIds[localSyncType] = deletedIds;
                }
            }
            ProcessPostEvents(parameter.Log, postEventTypes, dictDeletedIds, parameter.SynchronizationId, parameter.CustomInfo);
        }
            public static ApplyChangesResult FromPayload(JObject payload)
            {
                string synchronizationId = payload[nameof(SynchronizationId)].Value <string>();
                Dictionary <string, object> customInfo = payload[nameof(CustomInfo)].ToObject <Dictionary <string, object> >();
                PayloadAction      payloadAction       = (PayloadAction)Enum.Parse(typeof(PayloadAction), payload[nameof(PayloadAction)].Value <string>());
                ApplyChangesResult result = new ApplyChangesResult(payloadAction, synchronizationId, customInfo);

                result.Inserts           = payload[nameof(Inserts)].ToObject <List <SyncLog.SyncLogData> >();
                result.Updates           = payload[nameof(Updates)].ToObject <List <SyncLog.SyncLogData> >();
                result.Deletes           = payload[nameof(Deletes)].ToObject <List <SyncLog.SyncLogData> >();
                result.Conflicts         = payload[nameof(Conflicts)].ToObject <List <SyncLog.SyncLogConflict> >();
                result.PayloadAppliedIds = payload[nameof(PayloadAppliedIds)].ToObject <Dictionary <string, List <object> > >();
                return(result);
            }
Exemple #3
0
        /// <summary>
        /// Process pending changes - download thumbnails and update destination with batch document operations.
        /// </summary>
        private async Task <ApplyChangesResult> ApplyPendingChanges(
            IDocumentStorageProvider storage,
            IClient dropbox,
            ICollection <PendingChange> pendingChanges,
            Func <Task> batchProgressAction)
        {
            var result = new ApplyChangesResult();

            // filter changes according to specified options
            var filteredChanges = pendingChanges
                                  .Where(c =>
                                         c.Change == DocumentAction.Delete ||
                                         !_options.WithThumbnailsOnly || c.Meta.thumb_exists ||
                                         _options.IncludeSharedFolders || String.IsNullOrEmpty(c.Meta.parent_shared_folder_id)
                                         );

            var itemsProcessed = 0;

            // split accumulated changes to smaller batches to enable progress reporting and status checks
            foreach (var batch in filteredChanges.Chunkify(_options.ItemsPerBatch))
            {
                Debug.WriteLine("Processing next batch of changes [{0} / {1}]", itemsProcessed, pendingChanges.Count);

                // these will buffer metadata updates
                var documentsToDelete = new List <Document>();
                var documentsToUpdate = new List <Document>();
                var documentsToAdd    = new List <Document>();

                // create a list for thumbnail download tasks
                var thumbsToDownload = new List <PendingChange>();

                // sort through updates and adds
                foreach (var change in batch)
                {
                    if (change.Change != DocumentAction.Delete &&
                        _options.DownloadThumbnails && change.Meta.thumb_exists)
                    {
                        thumbsToDownload.Add(change);
                    }
                    else
                    {
                        var document = change.ToDocument();

                        switch (change.Change)
                        {
                        case DocumentAction.Add:
                            documentsToAdd.Add(document);
                            break;

                        case DocumentAction.Update:
                            documentsToUpdate.Add(document);
                            break;

                        case DocumentAction.Delete:
                            document.FilePath = change.DeletedFilePath;
                            documentsToDelete.Add(document);
                            break;
                        }
                    }
                }

                var downloadCount = await DownloadThumbnails(dropbox, thumbsToDownload, documentsToAdd, documentsToUpdate);

                result.Skipped += thumbsToDownload.Count - downloadCount;

                // now flush accumulated changes
                if (documentsToDelete.Count > 0)
                {
                    Debug.WriteLine("Deleting documents [{0}]", documentsToDelete.Count);
                    result.Deleted += await storage.DeleteAsync(documentsToDelete);
                }

                if (documentsToAdd.Count > 0)
                {
                    Debug.WriteLine("Adding documents [{0}]", documentsToUpdate.Count + documentsToAdd.Count);
                    result.Added += await storage.AddAsync(documentsToAdd);
                }
                if (documentsToUpdate.Count > 0)
                {
                    Debug.WriteLine("Updating documents [{0}]", documentsToUpdate.Count + documentsToAdd.Count);
                    result.Updated += await storage.UpdateAsync(documentsToUpdate);
                }

                if (batchProgressAction != null)
                {
                    await batchProgressAction();
                }

                itemsProcessed += _options.ItemsPerBatch;
            }

            return(result);
        }