コード例 #1
0
        private void ProcessExecOutputRemove(ItemChange <ConnectionViewModel> change)
        {
            if (change.Current.Input.Parent is CutNodeViewModel c)
            {
                Cut.BlockingCuts[0] = null;
                Cut.BlockingCuts[1] = null;
                Cut.BlockingCuts[2] = null;

                Cut = null;
                BlockingCutEditor.Value = null;

                if (Inputs.Items.First().Connections.Count > 0)
                {
                    ConnectionViewModel a = Inputs.Items.First().Connections.Items.First();

                    if (a.Output.Parent is CutNodeViewModel prev_c)
                    {
                        prev_c.Cut.NextCut = null;
                    }
                    else if (a.Output.Parent is BeginNodeViewModel begin)
                    {
                        begin.Actor.FirstCut = null;
                    }
                }
            }
        }
コード例 #2
0
ファイル: SyncReplicaMetadata.cs プロジェクト: alex765022/IBN
        public override IEnumerable <ItemChange> GetFullEnumerationLocalVersions(FullEnumerationChangeBatch sourceChanges)
        {
            if (sourceChanges == null)
            {
                throw new ArgumentNullException("sourceChanges");
            }
            foreach (ItemMetadata item in Replica.EntityMetadataItems)
            {
                ItemChange change = null;

                if ((item.GlobalId == sourceChanges.DestinationVersionEnumerationRangeLowerBound || item.GlobalId > sourceChanges.DestinationVersionEnumerationRangeLowerBound) &&
                    (item.GlobalId == sourceChanges.DestinationVersionEnumerationRangeUpperBound || item.GlobalId < sourceChanges.DestinationVersionEnumerationRangeUpperBound))
                {
                    // Found the corresponding item in the local metadata
                    // Get the local creation version and change (update) version from the metadata
                    change = new ItemChange(IdFormats, ReplicaId, item.GlobalId,
                                            item.IsDeleted ? ChangeKind.Deleted : ChangeKind.Update,      // If local item is a tombstone, mark it accordingly
                                            item.CreationVersion, item.ChangeVersion);
                }
                else
                {
                    // Remote item has no local counterpart
                    // This item is unknown to us
                    change = new ItemChange(IdFormats, ReplicaId, null,
                                            ChangeKind.UnknownItem,       // Mark the change as unknown
                                            SyncVersion.UnknownVersion, SyncVersion.UnknownVersion);
                }

                yield return(change);
            }
        }
コード例 #3
0
        private void ProcessExecOutputAdd(ItemChange <ConnectionViewModel> change)
        {
            if (change.Current.Input.Parent is CutNodeViewModel c)
            {
                Cut = c.Cut;
                BlockingCutEditor.Value = Cut;

                Cut.BlockingCuts[0] = BlockingCutEditor.BlockingCut1;
                Cut.BlockingCuts[1] = BlockingCutEditor.BlockingCut2;
                Cut.BlockingCuts[2] = BlockingCutEditor.BlockingCut3;

                if (Inputs.Items.First().Connections.Count > 0)
                {
                    ConnectionViewModel a = Inputs.Items.First().Connections.Items.First();

                    if (a.Output.Parent is CutNodeViewModel prev_c)
                    {
                        prev_c.Cut.NextCut = Cut;
                    }
                    else if (a.Output.Parent is BeginNodeViewModel begin)
                    {
                        begin.Actor.FirstCut = Cut;
                    }
                }

                Cut.ParentActor.UpdateCutList();
            }
        }
コード例 #4
0
        public async Task UpdateAsyncUsesIdentityComparerGivenAtConstruction()
        {
            IEnumerable <IntWrapper> originalItems         = new IntWrapper[] { 1, 2, 3 };
            IEnumerable <ItemChange <IntWrapper> > changes = new ItemChange <IntWrapper>[]
            {
                new ItemChange <IntWrapper>(ChangeType.Updated, 2)
            };

            var loader = new AsyncLoader <IntWrapper>(
                Seq.ListBased,
                loadDataAsync: _ => Task.FromResult(originalItems),
                fetchUpdatesAsync: (_, __) => Task.FromResult(changes),
                identityComparer: new IntWrapperComparer(),
                eventContext: new RunInlineSynchronizationContext());
            await loader.LoadAsync();  // load original items

            loader.CollectionChanged += (s, e) =>
            {
                // Verify that the resulting change was exactly the incoming change
                e.Should().Equal(changes);
            };

            await loader.UpdateAsync();  // --- Perform ---

            // Verify that no changes to the int values in the collection were made
            loader.Should().Equal(new IntWrapper[] { 1, 2, 3 }, (x, y) => x.Value == y.Value);
        }
コード例 #5
0
        public void PushItemChange()
        {
            var item = new Item("/test/test.txt")
            {
                ContentMetadata = new FileContentMetadata("text/plain", Encoding.UTF8)
            };
            var itemChange = new ItemChange(ItemChangeType.Add, item)
            {
                NewContent = new ItemContent(ItemContentType.RawText, "Testing")
            };
            var itemChanges = new ItemChange[] { itemChange };
            IEnumerable <ItemChange> itemChangesAdded = null;
            bool saveChangesCalled = false;
            var  fakeContext       = new Fakes.StubIDestinationContext()
            {
                AddItemChangesIEnumerableOfItemChange = (changes) => { itemChangesAdded = changes; },
                SaveChangesAsyncCancellationToken     = (token) =>
                {
                    saveChangesCalled = true;
                    return(Task.FromResult(0));
                }
            };
            var repo = new DestinationRepository(fakeContext);

            repo.PushItemChangesAsync(itemChanges, "/").Wait();

            Assert.IsNotNull(itemChangesAdded);
            Assert.AreEqual("test/test.txt", itemChangesAdded.Single().Item.Path);
            Assert.AreSame(itemChange.Item.ContentMetadata, itemChangesAdded.Single().Item.ContentMetadata);
            Assert.AreSame(itemChange.NewContent, itemChangesAdded.Single().NewContent);
            Assert.IsTrue(saveChangesCalled);
        }
コード例 #6
0
 private static void ValidateExistingChangeForAdd(ItemChange existingItem)
 {
     if ((existingItem.ChangeType & ItemChangeType.Delete) == 0)
     {
         throw new ApplicationException("Cannot add item on an existing item");
     }
 }
コード例 #7
0
        public async Task DownloadItemAndContentInCommitAsync(ItemChange change, string commitId, Guid repositoryId, CancellationToken token)
        {
            CreateHttpClient();

            var item = await _httpClient.GetItemAsync(
                repositoryId,
                change.Item.Path,
                includeContentMetadata : true,
                versionDescriptor : new Microsoft.TeamFoundation.SourceControl.WebApi.GitVersionDescriptor()
            {
                VersionType = Microsoft.TeamFoundation.SourceControl.WebApi.GitVersionType.Commit,
                Version     = commitId
            },
                cancellationToken : token
                );

            change.Item.ContentMetadata = item.ContentMetadata.ToSync();

            if (!item.IsFolder)
            {
                var content = await _httpClient.GetBlobContentAsync(repositoryId, item.ObjectId, cancellationToken : token);

                await change.SetNewContentAsync(content, token);
            }
        }
コード例 #8
0
 private void DoNothing(
     ItemMetadata item,
     ItemChange change,
     SaveChangeContext context,
     bool deleted = false,
     MegaNodeHelper existingNode = null)
 {
     // creating
     if (item == null)
     {
         if (existingNode == null)
         {
             context.RecordRecoverableErrorForItem(new RecoverableErrorData(new Exception()));
         }
         item = _metadataStore.Metadata.CreateItemMetadata(change.ItemId, change.CreationVersion);
         item.ChangeVersion = change.ChangeVersion;
         _metadataStore.SaveItemMetadata(item, existingNode.Node.Id, existingNode.Path);
         return;
     }
     if (deleted)
     {
         item.MarkAsDeleted(change.ChangeVersion);
     }
     item.ChangeVersion = change.ChangeVersion;
     _metadataStore.SaveItemMetadata(item);
 }
コード例 #9
0
        private void ProcessConstraint(
            ItemChange change,
            SaveChangeContext context,
            MegaStoreConstraintException e,
            ItemMetadata item,
            MegaNodeHelper conflictingNode)
        {
            switch (e.ConstraintType)
            {
            case MegaStoreConstraintType.TargetExists:
                ResolveConflict(item, change, context, conflictingNode);
                break;

            case MegaStoreConstraintType.NoParent:
                OnDemandedResync();
                context.RecordConstraintConflictForItem(ConstraintConflictReason.NoParent);
                break;

            // todo add no-free-space handling
            case MegaStoreConstraintType.ZeroSize:
                context.RecordConstraintConflictForItem(ConstraintConflictReason.Other);
                break;

            case MegaStoreConstraintType.NotEmpty:
                OnDemandedResync();
                context.RecordRecoverableErrorForItem(new RecoverableErrorData(e));
                break;
            }
        }
コード例 #10
0
        public void FailedAssertOfChangeAppendsReasonAsExpected()
        {
            var    change = new ItemChange <int>(ChangeType.Updated, 2);
            Action assert = () => change.Should().BeChange(ChangeType.Removed, 1, "because {0} should be removed", 1);

            assert.ShouldThrow <Exception>().WithMessage("*removal*of 1 because 1 should be removed*");
        }
コード例 #11
0
        public void CanAssertRemoval()
        {
            var change = new ItemChange <int>(ChangeType.Removed, 2);

            change.Should().BeOfChangeType(ChangeType.Removed);
            change.Should().BeRemoval();
        }
コード例 #12
0
        public void DownloadCommitWithAddedTextItem()
        {
            var push = CreatePushRequest("5597f65ce55386a771e4bf6fa190b5a26c0f5ce5");
            var fakeDownloadRequest = new Fakes.StubIDownloadRequest()
            {
                DownloadChangesInCommitAsyncStringGuidCancellationToken = (commitId, repositoryId, token) =>
                {
                    var changes = new ItemChange[]
                    {
                        new ItemChange(ItemChangeType.Add, new Item("/index.html"))
                    };
                    return(Task.FromResult(changes.AsEnumerable()));
                },
                DownloadItemAndContentInCommitAsyncItemChangeStringGuidCancellationToken = (itemChange, commitId, repositoryId, token) =>
                {
                    itemChange.Item.ContentMetadata = CreateTextContentMetadataTestData();
                    itemChange.NewContent           = CreateTextContentTestData();
                    return(Task.FromResult(0));
                }
            };
            var repo = new SourceRepository(fakeDownloadRequest);

            repo.DownloadChangesAsync(push, "/", CancellationToken.None).Wait();

            var change = push.Commits.Single().Changes.Single();

            Assert.AreEqual(ItemChangeType.Add, change.ChangeType);
            Assert.AreEqual("/index.html", change.Item.Path);
            Assert.IsNotNull(change.Item.ContentMetadata);
            Assert.IsFalse(change.Item.ContentMetadata.IsBinary);
            Assert.AreEqual("text/html", change.Item.ContentMetadata.ContentType);
            Assert.IsNotNull(change.NewContent);
            Assert.AreEqual(ItemContentType.RawText, change.NewContent.ContentType);
            Assert.AreEqual("Testing", change.NewContent.Content);
        }
コード例 #13
0
        public void CanAssertRemovalOfItem()
        {
            var change = new ItemChange <int>(ChangeType.Removed, 1);

            change.Should().BeChange(ChangeType.Removed, 1);
            change.Should().BeRemovalOf(1);
        }
コード例 #14
0
        public void ReplaceUsesIdentityComparerGivenAtConstruction()
        {
            var collectionChangedHandler = Substitute.For <CollectionChangedHandler <IntWrapper> >();

            IEnumerable <IntWrapper> originalItems = new IntWrapper[] { 1, 2, 3 };
            IntWrapper replacement = 2;

            IEnumerable <ItemChange <IntWrapper> > expectedChanges = new ItemChange <IntWrapper>[]
            {
                new ItemChange <IntWrapper>(ChangeType.Updated, replacement)
            };

            var loader = new ThreadSafeAsyncLoader <IntWrapper>(
                Seq.ListBased,
                loadDataAsync: _ => Task.FromResult(originalItems),
                identityComparer: new IntWrapperComparer(),
                eventContext: new RunInlineSynchronizationContext());

            loader.LoadAsync();  // load original items

            loader.CollectionChanged += collectionChangedHandler;
            loader.CollectionChanged += (s, e) =>
            {
                // Verify that the expected update was made
                e.Should().Equal(expectedChanges);
            };


            loader.Replace(replacement, replacement);  // --- Perform ---


            // Verify that changes were made by checking for collection changed events
            collectionChangedHandler.Received().Invoke(loader, Arg.Any <IEnumerable <ItemChange <IntWrapper> > >());
        }
コード例 #15
0
        public void ReplaceAllUsesIdentityComparerGivenAtConstruction()
        {
            IEnumerable <IntWrapper> originalItems = new IntWrapper[] { 1, 2, 3 };
            var replacements = new IntWrapper[] { 1, 3 };

            // NOTE: Due to conservate update check, unchanged items will appear as item changes of type update
            // NOTE2: Need to use the actual instances, since IntWrapper uses reference equality
            var expectedChanges = new ItemChange <IntWrapper>[]
            {
                new ItemChange <IntWrapper>(ChangeType.Updated, replacements[0]),
                new ItemChange <IntWrapper>(ChangeType.Updated, replacements[1]),
                new ItemChange <IntWrapper>(ChangeType.Removed, originalItems.ElementAt(1))
            };

            var loader = new ThreadSafeAsyncLoader <IntWrapper>(
                Seq.ListBased,
                loadDataAsync: _ => Task.FromResult(originalItems),
                identityComparer: new IntWrapperComparer(),
                eventContext: new RunInlineSynchronizationContext());

            loader.LoadAsync();  // load initial values
            loader.CollectionChanged += (s, e) =>
            {
                // Verify that the actual changes match the expected changes
                e.Should().BeEquivalentTo(expectedChanges);
            };


            loader.ReplaceAll(replacements);  // --- Perform ---
        }
コード例 #16
0
        private void LoadPropertiesForAll_OneCall()
        {
            if (lstChanges.Items.Count > 0)
            {
                this.Cursor = Cursors.WaitCursor;

                List <Item> oItemList = new List <Item>();

                foreach (ListViewItem oLVI in lstChanges.Items)
                {
                    ItemChange oItemChange = (ItemChange)oLVI.Tag;
                    oItemList.Add(oItemChange.Item);  // build a list of all items
                }

                StringBuilder oSB = new StringBuilder();
                oSB.AppendFormat("\r\n");
                oSB.AppendFormat("=================================================================================\r\n");
                oSB.AppendFormat("[ All Change Events in on call + LoadPropertiesForItems]=========================\r\n");
                oSB.AppendFormat("");


                oSB.Append(GatherChanges(oItemList));  // now do once call to get props for all.
                string sContent = oSB.ToString();

                ShowTextDocument oForm = new ShowTextDocument();
                oForm.txtEntry.WordWrap = false;
                oForm.Text          = "Properties for all items";
                oForm.txtEntry.Text = sContent;
                oForm.ShowDialog();

                this.Cursor = Cursors.Default;
            }
        }
コード例 #17
0
        private void ProcessChange(ItemChange change)
        {
            Debug.WriteLine("{0} {1}", change.ChangeType.ToString(), change.Item.Path);

            if ((change.ChangeType & ItemChangeType.Add) != 0)
            {
                AddChange(change);
            }
            else if ((change.ChangeType & ItemChangeType.Delete) != 0)
            {
                DeleteChange(change);
            }
            else if ((change.ChangeType & ItemChangeType.Edit) != 0)
            {
                EditChange(change);
            }
            else if ((change.ChangeType & ItemChangeType.Rename) != 0)
            {
                RenameChange(change);
            }
            else
            {
                // Ignore all other types
            }
        }
コード例 #18
0
 private static void ValidateExistingChangeForEdit(ItemChange existingChange)
 {
     if ((existingChange.ChangeType & ItemChangeType.Delete) != 0)
     {
         throw new ApplicationException("Cannot edit a deleted item");
     }
 }
コード例 #19
0
        public void CanAssertAddition()
        {
            var change = new ItemChange <int>(ChangeType.Added, 4);

            change.Should().BeOfChangeType(ChangeType.Added);
            change.Should().BeAddition();
        }
コード例 #20
0
        public void DownloadCommitWithAddedBinaryItem()
        {
            var push = CreatePushRequest("b6f447775f71a092854a2555eea084bd6d19958e");
            var fakeDownloadRequest = new Fakes.StubIDownloadRequest()
            {
                DownloadChangesInCommitAsyncStringGuidCancellationToken = (commitId, repositoryId, token) =>
                {
                    var changes = new ItemChange[]
                    {
                        new ItemChange(ItemChangeType.Add, new Item("/favicon.ico"))
                    };
                    return(Task.FromResult(changes.AsEnumerable()));
                },
                DownloadItemAndContentInCommitAsyncItemChangeStringGuidCancellationToken = (itemChange, commitId, repositoryId, token) =>
                {
                    itemChange.Item.ContentMetadata = CreateBinaryContentMetadataTestData();
                    itemChange.NewContent           = CreateBinaryContentTestData();
                    return(Task.FromResult(0));
                }
            };
            var repo = new SourceRepository(fakeDownloadRequest);

            repo.DownloadChangesAsync(push, "/", CancellationToken.None).Wait();

            var change = push.Commits.Single().Changes.Single();

            Assert.AreEqual(ItemChangeType.Add, change.ChangeType);
            Assert.AreEqual("/favicon.ico", change.Item.Path);
            Assert.IsTrue(change.Item.ContentMetadata.IsBinary);
            Assert.AreEqual("image/x-icon", change.Item.ContentMetadata.ContentType);
            Assert.IsNotNull(change.NewContent);
            Assert.AreEqual(ItemContentType.Base64Encoded, change.NewContent.ContentType);
            Assert.AreEqual(12, change.NewContent.Content.Length);
        }
コード例 #21
0
        public void CanAssertUpdateOfItem()
        {
            var change = new ItemChange <int>(ChangeType.Updated, 100);

            change.Should().BeChange(ChangeType.Updated, 100);
            change.Should().BeUpdateOf(100);
        }
コード例 #22
0
        public override void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context)
        {
            // Extract the data from the change
            TransferMechanism data = context.ChangeData as TransferMechanism;

            // Now apply the change
            if (!(saveChangeAction == SaveChangeAction.UpdateVersionOnly) && ((change.ChangeKind & ChangeKind.Deleted) == 0))
            {
                ItemMetadata item = new ItemMetadata();
                item.ItemId          = change.ItemId;
                item.ChangeVersion   = change.ChangeVersion;
                item.CreationVersion = change.CreationVersion;
                item.Uri             = data.Uri;

                RemoteFileInfo fileInfo = new RemoteFileInfo();
                fileInfo.FolderPath     = Path;
                fileInfo.Length         = data.DataStream.Length;
                fileInfo.Metadata       = item;
                fileInfo.FileByteStream = data.DataStream;
                Proxy.UploadFile(fileInfo);

                // Close input stream
                data.DataStream.Close();
            }
            else
            {
                Proxy.DeleteFile(Path, change.ItemId, _filters);
            }

            // If we made it here, the change was successfully applied locally
            // (or it is a version only change), so we can update our knowledge with the
            // learned knowledge from the change
            context.GetUpdatedDestinationKnowledge(out _syncKnowledge, out _forgottenKnowledge);
        }
コード例 #23
0
        public void CanAssertAdditionOfItem()
        {
            var change = new ItemChange <int>(ChangeType.Added, 5);

            change.Should().BeChange(ChangeType.Added, 5);
            change.Should().BeAdditionOf(5);
        }
コード例 #24
0
        public void AssertOfChangeDoesNotAcceptDifferentItem()
        {
            var    change = new ItemChange <int>(ChangeType.Added, 1);
            Action assert = () => change.Should().BeChange(ChangeType.Added, 2);

            assert.ShouldThrow <Exception>().WithMessage("Expected item change to be*addition*of 2*but found *addition*of*1*");
        }
コード例 #25
0
        public void CanAssertUpdate()
        {
            var change = new ItemChange <int>(ChangeType.Updated, 1);

            change.Should().BeOfChangeType(ChangeType.Updated);
            change.Should().BeUpdate();
        }
コード例 #26
0
        public List <ItemChange> GetChanges(ChangeBatch sourceChanges)
        {
            // Increment the tick count
            GetNextTickCount();

            // Increase local knowledge tick count.
            SyncKnowledge.SetLocalTickCount(tickCount);

            // Create a collection to hold the changes we'll put into our batch
            List <ItemChange> changes = new List <ItemChange>();

            foreach (ItemChange ic in sourceChanges)
            {
                ItemMetadata item;
                ItemChange   change;
                // Iterate through each item to get the corresponding version in the local store
                if (metadataStore.TryGetItem(ic.ItemId, out item))
                {
                    // Found the corresponding item in the local metadata
                    // Get the local creation version and change (update) version from the metadata
                    change = new ItemChange(IdFormats, ReplicaId, item.ItemId, item.IsTombstone ? ChangeKind.Deleted: ChangeKind.Update, item.CreationVersion, item.ChangeVersion);
                }
                else
                {
                    // Remote item has no local counterpart
                    // This item is unknown to us
                    change = new ItemChange(IdFormats, ReplicaId, ic.ItemId, ChangeKind.UnknownItem, SyncVersion.UnknownVersion, SyncVersion.UnknownVersion);
                }

                // Add our change to the change list
                changes.Add(change);
            }

            return(changes);
        }
コード例 #27
0
ファイル: SyncReplicaMetadata.cs プロジェクト: alex765022/IBN
        /// <summary>
        /// Detects changes not known to the destination and returns a change batch
        /// </summary>
        /// <param name="destinationKnowledge">Requester Knowledge</param>
        /// <param name="batchSize">Maximum number of changes to return</param>
        /// <returns>List of changes</returns>
        private List <ItemChange> DetectChanges(SyncKnowledge destinationKnowledge, SyncId lowerEnumerationBound, uint batchSize)
        {
            List <ItemChange> retVal = new List <ItemChange>();

            if (destinationKnowledge == null)
            {
                throw new ArgumentNullException("destinationKnowledge");
            }
            if (batchSize < 0)
            {
                throw new ArgumentOutOfRangeException("batchSize");
            }

            ulong currentLocalTickCount = Replica.TickCount;

            // Update local knowledge with the current local tick count
            Replica.CurrentKnowledge.SetLocalTickCount(currentLocalTickCount);

            // Map the destination knowledge
            // This maps the knowledge from the remote replica key map (where the destination is replicaKey 0)
            // to the local replica key map (where the source is replicaKey)
            //
            // We do this because our metadata is relative to the local store (and local key map)
            // (This is typical of most sync providers)
            SyncKnowledge mappedKnowledge = Replica.CurrentKnowledge.MapRemoteKnowledgeToLocal(destinationKnowledge);

            foreach (ItemMetadata item in Replica.EntityMetadataItems.Where(x => x.GlobalId.CompareTo(lowerEnumerationBound) >= 0))
            {
                // Check if the current version of the item is known to the destination
                // We simply check if the update version is contained in his knowledge

                // If the metadata is for a tombstone, the change is a delete

                if (!mappedKnowledge.Contains(Replica.ReplicaId, item.GlobalId, item.ChangeVersion))
                {
                    ItemChange itemChange = new ItemChange(IdFormats, Replica.ReplicaId, item.GlobalId,
                                                           item.IsDeleted ? ChangeKind.Deleted : ChangeKind.Update,
                                                           item.CreationVersion, item.ChangeVersion);

                    // Change isn't known to the remote store, so add it to the batch

                    retVal.Add(itemChange);
                }

                // If the batch is full, break
                //
                // N.B. Rest of changes will be detected in next batch. Current batch will not be
                // reenumerated (except in case destination doesn't successfully apply them) as
                // when destination applies the changes in this batch, they will add them to their
                // knowledge.

                if (retVal.Count == batchSize)
                {
                    break;
                }
            }

            return(retVal);
        }
コード例 #28
0
        public void FailedAssertOfChangeTypeAppendsReasonAsExpected()
        {
            var change = new ItemChange <int>(ChangeType.Removed, 333);

            Action assert = () => change.Should().BeOfChangeType(ChangeType.Added, "because I say so and also because {0} <> {1}", 1, 2);

            assert.ShouldThrow <Exception>().WithMessage("*to be*addition*because I say so and also because 1 <> 2, but*");
        }
コード例 #29
0
        public override void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context)
        {
            // Extract the data from the change
            TransferMechanism data = context.ChangeData as TransferMechanism;
            // Item metadata
            ItemMetadata item = _sync.GetItemMetaData(saveChangeAction, change, data);

            // Now apply the change
            if (!(saveChangeAction == SaveChangeAction.UpdateVersionOnly) && ((change.ChangeKind & ChangeKind.Deleted) == 0))
            {
                // Only copy if destination file name is known
                // (May have been lost if loser of name collision)
                if (item.Uri != String.Empty)
                {
                    FileInfo fi = new FileInfo(System.IO.Path.Combine(Path, item.Uri));
                    if (!fi.Directory.Exists)
                    {
                        fi.Directory.Create();
                    }

                    // Change should have stream data, so copy the file data to the local store
                    using (FileStream outputStream = new FileStream(System.IO.Path.Combine(Path, item.Uri), FileMode.OpenOrCreate)) {
                        const int copyBlockSize = 4096;
                        byte[]    buffer        = new byte[copyBlockSize];

                        int bytesRead;
                        // Simple block-by-block copy
                        while ((bytesRead = data.DataStream.Read(buffer, 0, copyBlockSize)) > 0)
                        {
                            outputStream.Write(buffer, 0, bytesRead);
                        }
                        // Truncate if needed
                        outputStream.SetLength(outputStream.Position);
                    }

                    // Update the last write time from the updated file to the metadata entry
                    item.LastWriteTimeUtc = fi.LastWriteTimeUtc;
                }

                // Close input stream
                data.DataStream.Close();
            }
            else
            {
                // Not an update/create, so must be a delete or version only change
                // Is it a delete?...
                if (item.IsTombstone && item.Uri != String.Empty)
                {
                    // Change is a delete
                    File.Delete(System.IO.Path.Combine(Path, item.Uri));
                }
            }

            // If we made it here, the change was successfully applied locally
            // (or it is a version only change), so we can update our knowledge with the
            // learned knowledge from the change
            _sync.GetUpdatedKnowledge(context);
        }
コード例 #30
0
 //Save the item, taking the appropriate action for the 'change' and the data from the item (in 'context')
 public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context)
 {
     ulong timeStamp = 0;
     ItemMetadata item = null;
     switch (saveChangeAction)
     {
         case SaveChangeAction.Create:
             item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId);
             if (item != null)
             {
                 // doubtful solution
                 _metadataStore.Metadata.RemoveItemMetadata(new List<SyncId> { item.GlobalId });
                 item = null;
             }
             CreateItem(change, context);
             break;
         case SaveChangeAction.UpdateVersionAndData:
         case SaveChangeAction.UpdateVersionOnly:
             item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId);
             if (item == null)
             {
                 CreateItem(change, context);
                 break;
             }
             if (saveChangeAction == SaveChangeAction.UpdateVersionOnly)
             {
                 item.ChangeVersion = change.ChangeVersion;
                 _metadataStore.SaveItemMetadata(item);
             }
             else { UpdateItem(item, change, context); }
             break;
         case SaveChangeAction.DeleteAndStoreTombstone:
             item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId);
             // didn't know about this item
             if (item == null)
             {
                 item = _metadataStore.Metadata.CreateItemMetadata(change.ItemId, change.CreationVersion);
                 item.MarkAsDeleted(change.ChangeVersion);
                 item.ChangeVersion = change.ChangeVersion;
                 _metadataStore.SaveItemMetadata(item);
             }
             else { DeleteItem(item, change, context); }
             break;
         case SaveChangeAction.UpdateVersionAndMergeData:
             item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId);
             ResolveConflict(item, change, context, null);
             break;
         case SaveChangeAction.DeleteAndRemoveTombstone:
             item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId);
             if (item != null)
             {
                 DeleteItem(item, change, context, true);
             }
             break;
     }
 }
コード例 #31
0
ファイル: CutNodeViewModel.cs プロジェクト: LordNed/Winditor
        private void ProcessPropertyInputAdd(ItemChange <ConnectionViewModel> change)
        {
            SubstanceNodeViewModel sub_view = change.Current.Output.Parent as SubstanceNodeViewModel;

            if (sub_view == null)
            {
                return;
            }

            Cut.Properties.Add(sub_view.Substance);
        }
コード例 #32
0
        public void ChangesFromReturnsCorrectChangesForDifferentSingletonSequences()
        {
            // Precondition: ItemChange implements Equals in natural way
            var change1 = new ItemChange<int>(ChangeType.Added, 1);
            var change2 = new ItemChange<int>(ChangeType.Added, 1);
            change1.Should().Be(change2);

            var oldSeq = new int[] { 1 };
            var newSeq = new int[] { 2 };
            IEnumerable<IItemChange<int>> expectedChanges = new[]
            {
                new ItemChange<int>(ChangeType.Removed, 1),
                new ItemChange<int>(ChangeType.Added, 2)
            };

            var changes = newSeq.ChangesFrom(oldSeq);  // --- Perform ---

            changes.Should().BeEquivalentTo(expectedChanges);
        }
コード例 #33
0
ファイル: RemoteStore.cs プロジェクト: labrinth1/RemoteSync
 public void SaveConflict(ItemChange conflictingChange, object conflictingChangeData, SyncKnowledge conflictingChangeKnowledge)
 {
     throw new NotImplementedException("The method or operation is not implemented.");
 }
コード例 #34
0
ファイル: SyncReplicaMetadata.cs プロジェクト: 0anion0/IBN
        /// <summary>
        /// Возвращает пакет изменений, содержащий версии элементов и базовые единицы, которые хранятся в данной реплике. 
        /// Они соответствуют элементам и базовым единицам, на которые были ссылки в пакете изменений, полученном от другого поставщика.
        /// </summary>
        /// <param name="sourceChanges">The source changes.</param>
        /// <returns></returns>
        public override IEnumerable<ItemChange> GetLocalVersions(ChangeBatch sourceChanges)
        {
            if (sourceChanges == null)
            {
                throw new ArgumentNullException("sourceChanges");
            }
            ulong tickCount = GetNextTickCount();

            Replica.CurrentKnowledge.SetLocalTickCount(tickCount);
            // Iterate over changes in the source ChangeBatch
            foreach (ItemChange itemChange in sourceChanges)
            {
                ItemChange change = null;
                ItemMetadata item = Replica.FindItemMetadataById(itemChange.ItemId);

                // Iterate through each item to get the corresponding version in the local store
                if (item != null)
                {
                    // Found the corresponding item in the local metadata
                    // Get the local creation version and change (update) version from the metadata
                    change = new ItemChange(IdFormats, ReplicaId, item.GlobalId,
                        item.IsDeleted ? ChangeKind.Deleted : ChangeKind.Update,  // If local item is a tombstone, mark it accordingly
                        item.CreationVersion, item.ChangeVersion);
                }
                else
                {
                    // Remote item has no local counterpart
                    // This item is unknown to us
                    change = new ItemChange(IdFormats, ReplicaId, itemChange.ItemId,
                        ChangeKind.UnknownItem,   // Mark the change as unknown
                        SyncVersion.UnknownVersion, SyncVersion.UnknownVersion);
                }

                // Add our change to the change list
                yield return change;
            }
        }
コード例 #35
0
 public void SaveConstraintConflict(
     ItemChange conflictingChange, 
     SyncId conflictingItemId,
     ConstraintConflictReason reason, 
     object conflictingChangeData,
     SyncKnowledge conflictingChangeKnowledge, 
     bool temporary)
 {
     var i = 1;
     // just to implement the interface
 }
コード例 #36
0
ファイル: SyncDetails.cs プロジェクト: labrinth1/RemoteSync
        public bool TryGetDestinationVersion(ItemChange sourceChange, out ItemChange destinationVersion)
        {
            ItemMetadata metadata;

            if (!metadataStore.TryGetItem(sourceChange.ItemId, out metadata))
            {
                destinationVersion = null;
                return false;
            }

            if (metadata == null)
            {
                destinationVersion = null;
                return false;
            }
            else
            {
                destinationVersion = new ItemChange(idFormats, replicaId, sourceChange.ItemId,
                        metadata.IsTombstone ? ChangeKind.Deleted : ChangeKind.Update,
                        metadata.CreationVersion, metadata.ChangeVersion);
                return true;
            }
        }
コード例 #37
0
ファイル: MySimpleSyncProvider.cs プロジェクト: 0anion0/IBN
        //Save the item, taking the appropriate action for the 'change' and the data from the item (in 'context')
        public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context)
        {
            Thread.Sleep(1000);

            ulong timeStamp = 0;
            ItemMetadata item = null;
            ItemData data = null;
            change.WorkEstimate = 1;
            switch (saveChangeAction)
            {
                case SaveChangeAction.Create:
                    //Do duplicate detection here
                    item = _metadata.FindItemMetadataById(change.ItemId);
                    if (null != item)
                    {
                        throw new Exception("SaveItemChange must not have Create action for existing items.");
                    }
                    item = _metadata.CreateItemMetadata(change.ItemId, change.CreationVersion);
                    item.ChangeVersion = change.ChangeVersion;
                    data = new ItemData( (ItemData)context.ChangeData);
                    //We are using the same id for both the local and global item id.
                    _store.CreateItem( data, change.ItemId.GetGuidId());
                    SaveItemMetadata(item, _store.Get(change.ItemId.GetGuidId()).TimeStamp);
                    break;

                case SaveChangeAction.UpdateVersionAndData:
                case SaveChangeAction.UpdateVersionOnly:
                    item = _metadata.FindItemMetadataById(change.ItemId);
                    if (null == item)
                    {
                        throw new Exception("Item Not Found in Store!?");
                    }

                    item.ChangeVersion = change.ChangeVersion;
                    if (saveChangeAction == SaveChangeAction.UpdateVersionOnly)
                    {
                        SaveItemMetadata(item);
                    }
                    else  //Also update the data and the timestamp.
                    {
                        data = new ItemData((ItemData)context.ChangeData);
                        timeStamp = _store.UpdateItem(item.GlobalId.GetGuidId(), data);
                        SaveItemMetadata(item, timeStamp);
                    }
                    break;

                case SaveChangeAction.DeleteAndStoreTombstone:
                    item = _metadata.FindItemMetadataById(change.ItemId);
                    if (null == item)
                    {
                        item = _metadata.CreateItemMetadata(change.ItemId, change.CreationVersion);
                    }

                    if (change.ChangeKind == ChangeKind.Deleted)
                    {
                        item.MarkAsDeleted(change.ChangeVersion);
                    }
                    else
                    {
                        // This should never happen in Sync Framework V1.0
                        throw new Exception("Invalid ChangeType");
                    }

                    item.ChangeVersion = change.ChangeVersion;
                    SaveItemMetadata(item, 0);  // set timestamp to 0 for tombstones
                    _store.DeleteItem(item.GlobalId.GetGuidId());
                    break;

                //Merge the changes! (Take the data from the local item + the remote item),noting to update the tick count to propagate the resolution!
                case SaveChangeAction.UpdateVersionAndMergeData:
                    item = _metadata.FindItemMetadataById(change.ItemId);

                    if (null == item)
                    {
                        throw new Exception("Item Not Found in Store!?");
                    }
                    if (item.IsDeleted != true)
                    {
                        //Note - you must update the change version to propagate the resolution!
                        item.ChangeVersion = new SyncVersion(0, _metadata.GetNextTickCount());

                        //Combine the conflicting data...
                        ItemData mergedData = (_store.Get(item.GlobalId.GetGuidId())).Merge( (ItemData)context.ChangeData);
                        timeStamp = _store.UpdateItem(item.GlobalId.GetGuidId(), mergedData);
                        SaveItemMetadata(item, timeStamp);
                    }
                    break;

                case SaveChangeAction.DeleteAndRemoveTombstone:
                    item = _metadata.FindItemMetadataById(change.ItemId);
                    if (item != null)
                    {
                        List<SyncId> ids = new List<SyncId>();
                        ids.Add(item.GlobalId);
                        _metadata.RemoveItemMetadata(ids);
                    }
                    _store.DeleteItem(change.ItemId.GetGuidId());
                    break;
            }
        }
コード例 #38
0
ファイル: LocalStore.cs プロジェクト: labrinth1/RemoteSync
 public void SaveConstraintConflict(ItemChange conflictingChange, SyncId conflictingItemId, ConstraintConflictReason reason, object conflictingChangeData, SyncKnowledge conflictingChangeKnowledge, bool temporary)
 {
     throw new NotImplementedException();
 }
コード例 #39
0
ファイル: SyncDetails.cs プロジェクト: labrinth1/RemoteSync
        public ChangeBatch GetChanges(ChangeBatch sourceChanges)
        {
            GetNextTickCount();
            myKnowledge.SetLocalTickCount(tickCount);

            List<ItemChange> changes = new List<ItemChange>();

            foreach (ItemChange ic in sourceChanges)
            {
                ItemMetadata item;
                ItemChange change;

                if (metadataStore.TryGetItem(ic.ItemId, out item))
                {
                    System.Diagnostics.Debug.WriteLine("Remote item has   local counterpart::" + item.Uri);
                    change = new ItemChange(IdFormats, ReplicaId, item.ItemId,
                        (item.IsTombstone ? ChangeKind.Deleted : ChangeKind.Update),
                        item.CreationVersion, item.ChangeVersion);

                }
                else
                {
                    if (item == null)
                        System.Diagnostics.Debug.WriteLine("Remote item has no local counterpart: item.uri is null");
                    else
                        System.Diagnostics.Debug.WriteLine("Remote item has no local counterpart:" + item.Uri);

                    change = new ItemChange(IdFormats, replicaId, ic.ItemId, ChangeKind.UnknownItem,
                        SyncVersion.UnknownVersion, SyncVersion.UnknownVersion);

                }
                changes.Add(change);
            }

            ChangeBatch changeBatchBuilder = new ChangeBatch(IdFormats, myKnowledge , myForgottenKnowledge);

            changeBatchBuilder.BeginUnorderedGroup();

            changeBatchBuilder.AddChanges(changes);

            changeBatchBuilder.EndUnorderedGroup(myKnowledge, true);

            return changeBatchBuilder;
        }
コード例 #40
0
        private void BackupFile(ItemMetadata item, string path, ItemChange change, SaveChangeContext context)
        {
            var t = _nodeStore.BackupFile(path);
            var newItem = _metadataStore.CreateItemMetadata();
            _metadataStore.SaveItemMetadata(newItem, t.Node.Id, t.Path);

            if (item == null)
            {
                CreateItem(change, context);
            }
            else
            {
                UpdateItem(item, change, context);
            }
        }
コード例 #41
0
 /// <summary>
 /// CONFLICT
 /// </summary>
 private void ResolveConflict(ItemMetadata item, ItemChange change, SaveChangeContext context, MegaNodeHelper conflictingNode)
 {
     var data = (IFileDataRetriever)context.ChangeData;
     // item does not exist in metadata (can happen when create+create)
     if (item == null) 
     {
         if (conflictingNode == null) 
         {
             context.RecordRecoverableErrorForItem(new RecoverableErrorData(new Exception()));
         }
         if (FilesAreEqual(data, conflictingNode))
         {
             DoNothing(item, change, context, false, conflictingNode);
         }
         else
         {
             BackupFile(item, conflictingNode.Path, change, context);
         }
         return;
     }
     var attr = _metadataStore.GetItemInfo(item);
     try
     {
         if (change.ChangeKind == ChangeKind.Deleted)
         {
             // local delete + remote delete
             if (item.IsDeleted)
             {
                 DoNothing(item, change, context, true);
             }
             // local delete + remote update
             else
             {
                 DownloadBack(item, change);
             }
         }
         else
         {
             // local update + remote delete
             if (item.IsDeleted)
             {
                 UploadBack(item, change, context);
             }
             // update + update
             else
             {
                 if (FilesAreEqual(data, _nodeStore.FindNodeById(attr.Id)))
                 {
                     DoNothing(item, change, context);
                 }
                 else
                 {
                     BackupFile(item, attr.Path, change, context);
                 }
             }
         }
     }
     catch (MegaApiException e)
     {
         context.RecordRecoverableErrorForItem(new RecoverableErrorData(e));
     }
 }
コード例 #42
0
 private void UploadBack(ItemMetadata item, ItemChange change, SaveChangeContext context)
 {
     //TODO this still re-downloads the file just uploaded
     item.ResurrectDeletedItem();
     CreateItem(change, context, item);
 }
コード例 #43
0
 private void DownloadBack(ItemMetadata item, ItemChange change)
 {
     item.ChangeVersion = new SyncVersion(change.ChangeVersion.ReplicaKey, GetNextTickCount());
     _metadataStore.SaveItemMetadata(item);
 }
コード例 #44
0
 private void DoNothing(
     ItemMetadata item, 
     ItemChange change,
     SaveChangeContext context,
     bool deleted = false,
     MegaNodeHelper existingNode = null)
 {
     // creating
     if (item == null)
     {
         if (existingNode == null)
         {
             context.RecordRecoverableErrorForItem(new RecoverableErrorData(new Exception()));
         }
         item = _metadataStore.Metadata.CreateItemMetadata(change.ItemId, change.CreationVersion);
         item.ChangeVersion = change.ChangeVersion;
         _metadataStore.SaveItemMetadata(item, existingNode.Node.Id, existingNode.Path);
         return;
     }
     if (deleted)
     {
         item.MarkAsDeleted(change.ChangeVersion);
     }
     item.ChangeVersion = change.ChangeVersion;
     _metadataStore.SaveItemMetadata(item);
 }
コード例 #45
0
        private void ProcessConstraint(
            ItemChange change,
            SaveChangeContext context,
            MegaStoreConstraintException e,
            ItemMetadata item,
            MegaNodeHelper conflictingNode)
        {
            switch (e.ConstraintType)
            {
                case MegaStoreConstraintType.TargetExists:
                    ResolveConflict(item, change, context, conflictingNode);
                    break;

                case MegaStoreConstraintType.NoParent:
                    OnDemandedResync();
                    context.RecordConstraintConflictForItem(ConstraintConflictReason.NoParent);
                    break;
                // todo add no-free-space handling
                case MegaStoreConstraintType.ZeroSize:
                    context.RecordConstraintConflictForItem(ConstraintConflictReason.Other);
                    break;

                case MegaStoreConstraintType.NotEmpty:
                    OnDemandedResync();
                    context.RecordRecoverableErrorForItem(new RecoverableErrorData(e));
                    break;
            }
        }
コード例 #46
0
 public void SaveConflict(ItemChange conflictingChange, object conflictingChangeData, SyncKnowledge conflictingChangeKnowledge)
 {
     //Conflicts are always merged so there is never a conflict to save.  See DestinationCallbacks_ItemConflicting in MyTestProgram 
     //and the SaveChangeAction.UpdateVersionAndMergeData case in SaveChange below to see how conflicts are merged.
     throw new NotImplementedException();
 }
コード例 #47
0
ファイル: RemoteStore.cs プロジェクト: labrinth1/RemoteSync
        public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context)
        {
            DataTransfer data = context.ChangeData as DataTransfer;

            switch (saveChangeAction)
            {
                case SaveChangeAction.Create:
                    {
                        ItemMetadata item = new ItemMetadata();
                        item.ItemId = change.ItemId;
                        item.ChangeVersion = change.ChangeVersion;
                        item.CreationVersion = change.CreationVersion;
                        item.Uri = data.Uri;

                        data.DataStream.Position = 0;
                        System.Diagnostics.Debug.WriteLine("Uploading File:" + item.Uri);
                        service.UploadFile(data.DataStream.Length, item, data.DataStream);

                        data.DataStream.Close();
                        sync.UpdateItemItem(item);

                        break;
                    }
                case SaveChangeAction.DeleteAndStoreTombstone:
                    {
                        ItemMetadata item = sync.GetItemMetaData(saveChangeAction, change, data);

                        sync.DeleteItem(change.ItemId);
                        service.DeleteFile(change.ItemId, item.Uri);
                        break;
                    }
                default:
                    {
                        throw new NotImplementedException(saveChangeAction + " ChangeAction is not implemented!");
                    }

            }

            context.GetUpdatedDestinationKnowledge(out myKnowledge, out myForgottenKnowledge);
        }
コード例 #48
0
 /// <summary>
 /// DELETE
 /// </summary>
 private void DeleteItem(ItemMetadata item, ItemChange change, SaveChangeContext context, bool removeTombstone = false)
 {
     try
     {
         var attr = _metadataStore.GetItemInfo(item);
         _nodeStore.DeleteFile(attr.Path, attr.Id);
         OnAppliedChange(ChangeType.Delete, null, attr.Path);
         if (removeTombstone)
         {
             _metadataStore.Metadata.RemoveItemMetadata(new List<SyncId> { item.GlobalId });
         }
         else
         {
             item.MarkAsDeleted(change.ChangeVersion);
             _metadataStore.SaveItemMetadata(item);
         }
     }
     catch (MegaStoreConstraintException e)
     {
         ProcessConstraint(change, context, e, item, null);
     }
     // never mind, the item isn't found anyway
     catch (MegaStoreException)
     {
         if (removeTombstone)
         {
             _metadataStore.Metadata.RemoveItemMetadata(new List<SyncId> { item.GlobalId });
         }
         else
         {
             item.MarkAsDeleted(change.ChangeVersion);
             _metadataStore.SaveItemMetadata(item);
         }
     }
     catch (MegaApiException e)
     {
         context.RecordRecoverableErrorForItem(new RecoverableErrorData(e));
         OnDemandedResync();
     }
 }
コード例 #49
0
ファイル: RemoteStore.cs プロジェクト: labrinth1/RemoteSync
 public bool TryGetDestinationVersion(ItemChange sourceChange, out ItemChange destinationVersion)
 {
     destinationVersion = null;
     return false;
 }
コード例 #50
0
        /// <summary>
        /// UPDATE
        /// </summary>
        /// 
        private void UpdateItem(ItemMetadata item, ItemChange change, SaveChangeContext context)
        {
            var data = (IFileDataRetriever)context.ChangeData;
            var attr = _metadataStore.GetItemInfo(item);
            var stream = data.FileData.IsDirectory ? null : data.FileStream;
            try
            {
                SyncedNodeAttributes updatedNode = null;
                //if pathes are different then consider renaming with unchanged content
                if (attr.Path != data.FileData.RelativePath)
                {
                    updatedNode = _nodeStore.MoveFile(attr.Path, data.FileData.RelativePath, attr.Id);
                    OnAppliedChange(ChangeType.Rename, data.FileData.RelativePath, attr.Path);
                }
                else
                {
                    updatedNode = _nodeStore.UpdateFile(attr.Path, data.FileData, stream, attr.Id);
                    OnAppliedChange(ChangeType.Update, data.FileData.RelativePath);
                }

                item.ChangeVersion = change.ChangeVersion;
                _metadataStore.SaveItemMetadata(item, updatedNode.Id, updatedNode.Path);
            }
            catch (MegaStoreConstraintException e)
            {
                ProcessConstraint(change, context, e, item, e.Node);
            }
            catch (MegaStoreException e)
            {
                ForgetItem(context, item, e);
            }
            catch (MegaApiException e)
            {
                context.RecordRecoverableErrorForItem(new RecoverableErrorData(e));
                OnDemandedResync();
            }
            catch (DirectoryNotFoundException e)
            {
                context.RecordRecoverableErrorForItem(new RecoverableErrorData(e));
                OnDemandedResync();
            }

            catch (COMException e)
            {
                OnDemandedResync();
                context.RecordRecoverableErrorForItem(new RecoverableErrorData(e));
            }
            finally
            {
                CloseStream(stream);
            }
        }
コード例 #51
0
ファイル: LocalStore.cs プロジェクト: labrinth1/RemoteSync
 public void SaveChangeWithChangeUnits(ItemChange change, SaveChangeWithChangeUnitsContext context)
 {
     throw new NotImplementedException();
 }
コード例 #52
0
        /// <summary>
        /// CREATE
        /// </summary>
        private void CreateItem(ItemChange change, SaveChangeContext context, ItemMetadata itemToSaveChanges = null)
        {
            var data = (IFileDataRetriever)context.ChangeData;
            Stream stream = null;
            try
            {
                stream = data.FileData.IsDirectory ? null : data.FileStream;
                var createdNode = _nodeStore.InsertNode(data.FileData, data.FileData.RelativePath, stream);
                if (itemToSaveChanges == null)
                {
                    itemToSaveChanges = _metadataStore.CreateItemMetadata(change.ItemId, change.CreationVersion);
                }
                itemToSaveChanges.ChangeVersion = change.ChangeVersion;

                _metadataStore.SaveItemMetadata(itemToSaveChanges, createdNode.Id, createdNode.Path);
                OnAppliedChange(ChangeType.Create, data.FileData.RelativePath);
            }
            catch (MegaStoreConstraintException e)
            {
                ProcessConstraint(change, context, e, null, e.Node);
            }
            catch (MegaApiException e)
            {
                context.RecordRecoverableErrorForItem(new RecoverableErrorData(e));
            }
            catch (DirectoryNotFoundException e)
            {
                OnDemandedResync();
                context.RecordRecoverableErrorForItem(new RecoverableErrorData(e));
            }
            catch (COMException e)
            {
                OnDemandedResync();
                context.RecordRecoverableErrorForItem(new RecoverableErrorData(e));
            }
            finally
            {
                CloseStream(stream);
            }
        }
コード例 #53
0
ファイル: SyncDetails.cs プロジェクト: labrinth1/RemoteSync
        public ItemMetadata GetItemMetaData(SaveChangeAction saveChangeAction, ItemChange change, DataTransfer data)
        {
            ItemMetadata item;
            if (saveChangeAction == SaveChangeAction.UpdateVersionOnly || ((change.ChangeKind & ChangeKind.Deleted) == ChangeKind.Deleted))
            {
                if (!metadataStore.TryGetItem(change.ItemId, out item))
                {
                    item = new ItemMetadata();
                    item.Uri = String.Empty;
                }
            }
            else
            {
                item = new ItemMetadata();
                item.Uri = data.Uri;
            }

            item.ItemId = change.ItemId;
            item.CreationVersion = change.CreationVersion;
            item.ChangeVersion = change.ChangeVersion;

            if ((change.ChangeKind & ChangeKind.Deleted) == ChangeKind.Deleted)
                item.IsTombstone = true;

            if (!metadataStore.Has(item.ItemId))
            {
                ItemMetadata oldItem;

                if (metadataStore.TryGetItem(item.Uri, out oldItem))
                {

                    if (item.ItemId.CompareTo(oldItem.ItemId) > 0)
                    {
                        oldItem.IsTombstone = true;
                        oldItem.Uri = String.Empty;
                        oldItem.ChangeVersion = new SyncVersion(0, tickCount);
                    }
                    else
                    {
                        item.IsTombstone = true;
                        item.Uri = String.Empty;
                        item.ChangeVersion = new SyncVersion(0, tickCount);
                    }
                    metadataStore.SetItemInfo(item);
                    metadataStore.SetItemInfo(oldItem);
                }
            }
            metadataStore.SetItemInfo(item);

            return item;
        }
コード例 #54
0
ファイル: LocalStore.cs プロジェクト: labrinth1/RemoteSync
 public bool TryGetDestinationVersion(ItemChange sourceChange, out ItemChange destinationVersion)
 {
     return sync.TryGetDestinationVersion(sourceChange, out destinationVersion);
 }
コード例 #55
0
ファイル: SyncDetails.cs プロジェクト: labrinth1/RemoteSync
        private List<ItemChange> DetectChanges(SyncKnowledge destinationKnowledge, uint batchSize)
        {
            System.Diagnostics.Debug.WriteLine(" Start DetectChanges in:" + folderPath);

            List<ItemChange> changeBatch = new List<ItemChange>();

            if (destinationKnowledge == null)
                throw new ArgumentNullException("destinationKnowledge");

            if (batchSize < 0)
                throw new ArgumentOutOfRangeException("batchSize");

            if (!localChangedDetected)
            {
                FindLocalFileChanges(folderPath);
                localChangedDetected = true;
            }

            SyncKnowledge mappedKnowledge = myKnowledge.MapRemoteKnowledgeToLocal(destinationKnowledge);

            System.Diagnostics.Debug.WriteLine("  Is the current version of the item is known to the destination ?");
            foreach (ItemMetadata item in metadataStore)
            {
                if (!mappedKnowledge.Contains(replicaId, item.ItemId, item.ChangeVersion))// Create
                {
                    System.Diagnostics.Debug.WriteLine("Not Known:" + item.Uri + " IsTombstone:" + item.IsTombstone.ToString());
                    ItemChange itemChange = new ItemChange(IdFormats, replicaId, item.ItemId,
                        (item.IsTombstone) ? ChangeKind.Deleted : ChangeKind.Update,
                        item.CreationVersion, item.ChangeVersion);

                    changeBatch.Add(itemChange);
                }
                else if (item.IsTombstone)//Delete
                {
                    System.Diagnostics.Debug.WriteLine("Item is Known:" + item.Uri + " Its a Tombstone so add it:");

                    ItemChange itemChange = new ItemChange(IdFormats, replicaId, item.ItemId, ChangeKind.Deleted, item.CreationVersion, item.ChangeVersion);
                    changeBatch.Add(itemChange);
                }
                else//Update
                {
                    System.Diagnostics.Debug.WriteLine("mappedKnowledge is know item " + item.Uri + " And was no tombstone");
                    ItemChange itemChange = new ItemChange(IdFormats, replicaId, item.ItemId, ChangeKind.Update,
                        item.CreationVersion, item.ChangeVersion);

                    changeBatch.Add(itemChange);
                }

                if (changeBatch.Count == batchSize)
                    break;
            }
            System.Diagnostics.Debug.WriteLine("        #### End DetectChanges ####");
            return changeBatch;
        }
コード例 #56
0
ファイル: LocalStore.cs プロジェクト: labrinth1/RemoteSync
        /// <summary>
        /// Download Mechanism
        /// </summary>
        /// <param name="saveChangeAction"></param>
        /// <param name="change"></param>
        /// <param name="context"></param>
        public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context)
        {
            DataTransfer data = context.ChangeData as DataTransfer;

            ItemMetadata item = sync.GetItemMetaData(saveChangeAction, change, data);
            switch (saveChangeAction)
            {
                case SaveChangeAction.Create:
                    {
                        System.Diagnostics.Debug.WriteLine("Create File: " + item.Uri);
                        UpdateOrCreateFile(data, item);

                        break;
                    }
                case SaveChangeAction.UpdateVersionAndData:
                        {
                            System.Diagnostics.Debug.WriteLine("UpdateVersion And Data File: " + item.Uri);
                            UpdateOrCreateFile(data, item);

                        break;
                        }
                case SaveChangeAction.DeleteAndStoreTombstone:
                    {
                        System.Diagnostics.Debug.WriteLine("   Delete File: " + item.Uri);
                        File.Delete(Path.Combine(folderPath, item.Uri));
                        break;
                    }
                default:
                    {
                        throw new NotImplementedException(saveChangeAction + " ChangeAction is not implemented!");
                    }

            }
            sync.GetUpdatedKnowledge(context);
        }
コード例 #57
0
ファイル: SyncReplicaMetadata.cs プロジェクト: 0anion0/IBN
        /// <summary>
        /// Detects changes not known to the destination and returns a change batch
        /// </summary>
        /// <param name="destinationKnowledge">Requester Knowledge</param>
        /// <param name="batchSize">Maximum number of changes to return</param>
        /// <returns>List of changes</returns>
        private List<ItemChange> DetectChanges(SyncKnowledge destinationKnowledge, SyncId lowerEnumerationBound, uint batchSize)
        {
            List<ItemChange> retVal = new List<ItemChange>();

            if (destinationKnowledge == null)
                throw new ArgumentNullException("destinationKnowledge");
            if (batchSize < 0)
                throw new ArgumentOutOfRangeException("batchSize");

            ulong currentLocalTickCount = Replica.TickCount;

            // Update local knowledge with the current local tick count
            Replica.CurrentKnowledge.SetLocalTickCount(currentLocalTickCount);

            // Map the destination knowledge
            // This maps the knowledge from the remote replica key map (where the destination is replicaKey 0)
            // to the local replica key map (where the source is replicaKey)
            //
            // We do this because our metadata is relative to the local store (and local key map)
            // (This is typical of most sync providers)
            SyncKnowledge mappedKnowledge = Replica.CurrentKnowledge.MapRemoteKnowledgeToLocal(destinationKnowledge);

            foreach (ItemMetadata item in Replica.EntityMetadataItems.Where(x => x.GlobalId.CompareTo(lowerEnumerationBound) >= 0))
            {
                // Check if the current version of the item is known to the destination
                // We simply check if the update version is contained in his knowledge

                // If the metadata is for a tombstone, the change is a delete

                if (!mappedKnowledge.Contains(Replica.ReplicaId, item.GlobalId, item.ChangeVersion))
                {
                    ItemChange itemChange = new ItemChange(IdFormats, Replica.ReplicaId, item.GlobalId,
                        item.IsDeleted ? ChangeKind.Deleted : ChangeKind.Update,
                        item.CreationVersion, item.ChangeVersion);

                    // Change isn't known to the remote store, so add it to the batch

                    retVal.Add(itemChange);
                }

                // If the batch is full, break
                //
                // N.B. Rest of changes will be detected in next batch. Current batch will not be
                // reenumerated (except in case destination doesn't successfully apply them) as
                // when destination applies the changes in this batch, they will add them to their
                // knowledge.

                if (retVal.Count == batchSize)
                    break;
            }

            return retVal;
        }
コード例 #58
0
ファイル: RemoteStore.cs プロジェクト: labrinth1/RemoteSync
 public void SaveChangeWithChangeUnits(ItemChange change, SaveChangeWithChangeUnitsContext context)
 {
     throw new NotImplementedException("The method or operation is not implemented.");
 }
コード例 #59
0
 public void SaveChangeWithChangeUnits(ItemChange change, SaveChangeWithChangeUnitsContext context)
 {
     //Change units are not supported by this sample provider.  
     throw new NotImplementedException();
 }
コード例 #60
0
        public bool TryGetDestinationVersion(ItemChange sourceChange, out ItemChange destinationVersion)
        {
            ItemMetadata metadata = _metadataStore.Metadata.FindItemMetadataById(sourceChange.ItemId);

            if (metadata == null)
            {
                destinationVersion = null;
                return false;
            }
            else
            {
                destinationVersion = new ItemChange(_idFormats, _metadataStore.ReplicaId, sourceChange.ItemId,
                        metadata.IsDeleted ? ChangeKind.Deleted : ChangeKind.Update,
                        metadata.CreationVersion, metadata.ChangeVersion);
                return true;
            }
        }