private void AddSyncEntriesRecursive( SyncDatabase db, List <EntryUpdateInfo> updatesToRestore, SyncEntry syncEntry, RestoreOnlyWindowsFileSystemAdapter destAdapter) { EntryUpdateInfo updateInfo = new EntryUpdateInfo( syncEntry, destAdapter, SyncEntryChangedFlags.Restored, syncEntry.GetRelativePath(db, "/")); updatesToRestore.Add(updateInfo); if (syncEntry.Type == SyncEntryType.Directory) { List <SyncEntry> childEntries = db.Entries.Where(e => e.ParentId == syncEntry.Id).ToList(); foreach (SyncEntry childEntry in childEntries) { this.AddSyncEntriesRecursive(db, updatesToRestore, childEntry, destAdapter); } } }
protected override async Task ExecuteTask() { if (!this.syncEntries.Any()) { return; } RestoreOnlyWindowsFileSystemAdapterConfiguration adapterConfig = new RestoreOnlyWindowsFileSystemAdapterConfiguration { RootDirectory = this.restorePath }; RestoreOnlyWindowsFileSystemAdapter destAdapter = new RestoreOnlyWindowsFileSystemAdapter(this.Relationship, adapterConfig); List <EntryUpdateInfo> updatesToRestore = new List <EntryUpdateInfo>(); using (var db = this.Relationship.GetDatabase()) { foreach (SyncEntry syncEntry in this.syncEntries) { this.AddSyncEntriesRecursive(db, updatesToRestore, syncEntry, destAdapter); } } updatesToRestore.Sort(new EntryProcessingSorter()); RestoreResult result = new RestoreResult(); if (this.Relationship.EncryptionMode != Configuration.EncryptionMode.None) { X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly); var cert = store.Certificates.Find( X509FindType.FindByThumbprint, this.Relationship.EncryptionCertificateThumbprint, false); this.encryptionCertificate = cert[0]; } this.filesCompleted = 0; this.bytesCompleted = 0; foreach (EntryUpdateInfo entryUpdateInfo in updatesToRestore) { if (this.CancellationToken.IsCancellationRequested) { result.Cancelled = true; return; } RestoreItemResult itemResult = new RestoreItemResult(entryUpdateInfo); string message = string.Empty; try { AdapterBase sourceAdapter = this.Relationship.Adapters.FirstOrDefault( a => a.Configuration.Flags != AdapterFlags.Originator); await this.RestoreFileAsync( entryUpdateInfo, sourceAdapter, destAdapter) .ConfigureAwait(false); message = "The change was successfully synchronized"; } catch (TaskCanceledException) { result.Cancelled = true; Logger.Warning("Processing was cancelled"); message = "The change was cancelled during processing"; itemResult.ErrorMessage = "Processing was cancelled"; itemResult.State = EntryUpdateState.Failed; } catch (Exception exception) { Logger.Warning( "Processing failed with {0}: {1}", exception.GetType().FullName, exception.Message); message = "An error occurred while synchronzing the changed."; itemResult.ErrorMessage = exception.Message; itemResult.State = EntryUpdateState.Failed; } finally { Interlocked.Increment(ref this.filesCompleted); Logger.ChangeSynchronzied( Logger.BuildEventMessageWithProperties( message, new Dictionary <string, object>())); } } }