Example #1
0
        public void TestFindMissingRevisions()
        {
            var revs = new RevisionList();

            database.Storage.FindMissingRevisions(revs);

            var doc1r1 = PutDoc(new Dictionary <string, object> {
                ["_id"] = "11111",
                ["key"] = "one"
            });
            var doc2r1 = PutDoc(new Dictionary <string, object> {
                ["_id"] = "22222",
                ["key"] = "two"
            });

            PutDoc(new Dictionary <string, object> {
                ["_id"] = "33333",
                ["key"] = "three"
            });
            PutDoc(new Dictionary <string, object> {
                ["_id"] = "44444",
                ["key"] = "four"
            });
            PutDoc(new Dictionary <string, object> {
                ["_id"] = "55555",
                ["key"] = "five"
            });

            var doc1r2 = PutDoc(new Dictionary <string, object> {
                ["_id"]  = "11111",
                ["_rev"] = doc1r1.RevID.ToString(),
                ["key"]  = "one+"
            });
            var doc2r2 = PutDoc(new Dictionary <string, object> {
                ["_id"]  = "22222",
                ["_rev"] = doc2r1.RevID.ToString(),
                ["key"]  = "two+"
            });

            PutDoc(new Dictionary <string, object> {
                ["_id"]      = "11111",
                ["_rev"]     = doc1r2.RevID.ToString(),
                ["_deleted"] = true
            });

            // Now call FindMissingRevisions
            var revToFind1 = new RevisionInternal("11111", "3-6060".AsRevID(), false);
            var revToFind2 = new RevisionInternal("22222", doc2r2.RevID, false);
            var revToFind3 = new RevisionInternal("99999", "9-4141".AsRevID(), false);

            revs = new RevisionList(new List <RevisionInternal> {
                revToFind1, revToFind2, revToFind3
            });
            database.Storage.FindMissingRevisions(revs);
            CollectionAssert.AreEqual(new List <RevisionInternal> {
                revToFind1, revToFind3
            }, revs);

            // Check the possible ancestors
            ValueTypePtr <bool> haveBodies = false;

            CollectionAssert.AreEqual(new List <RevisionID> {
                doc1r2.RevID, doc1r1.RevID
            }, database.Storage.GetPossibleAncestors(revToFind1, 0, haveBodies));
            CollectionAssert.AreEqual(new List <RevisionID> {
                doc1r2.RevID
            }, database.Storage.GetPossibleAncestors(revToFind1, 1, haveBodies));
            CollectionAssert.AreEqual(new List <RevisionID>(), database.Storage.GetPossibleAncestors(revToFind3, 0, haveBodies));
        }
        /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
        public virtual void TestCRUDOperations()
        {
            database.AddChangeListener(this);
            string privateUUID = database.PrivateUUID();
            string publicUUID  = database.PublicUUID();

            Log.V(Tag, "DB private UUID = '" + privateUUID + "', public UUID = '" + publicUUID
                  + "'");
            NUnit.Framework.Assert.IsTrue(privateUUID.Length >= 20);
            NUnit.Framework.Assert.IsTrue(publicUUID.Length >= 20);
            //create a document
            IDictionary <string, object> documentProperties = new Dictionary <string, object>();

            documentProperties.Put("foo", 1);
            documentProperties.Put("bar", false);
            documentProperties.Put("baz", "touch");
            Body             body   = new Body(documentProperties);
            RevisionInternal rev1   = new RevisionInternal(body, database);
            Status           status = new Status();

            rev1 = database.PutRevision(rev1, null, false, status);
            Log.V(Tag, "Created " + rev1);
            NUnit.Framework.Assert.IsTrue(rev1.GetDocId().Length >= 10);
            NUnit.Framework.Assert.IsTrue(rev1.GetRevId().StartsWith("1-"));
            //read it back
            RevisionInternal readRev = database.GetDocumentWithIDAndRev(rev1.GetDocId(), null
                                                                        , EnumSet.NoneOf <Database.TDContentOptions>());

            NUnit.Framework.Assert.IsNotNull(readRev);
            IDictionary <string, object> readRevProps = readRev.GetProperties();

            NUnit.Framework.Assert.AreEqual(UserProperties(readRevProps), UserProperties(body
                                                                                         .GetProperties()));
            //now update it
            documentProperties = readRev.GetProperties();
            documentProperties.Put("status", "updated!");
            body = new Body(documentProperties);
            RevisionInternal rev2      = new RevisionInternal(body, database);
            RevisionInternal rev2input = rev2;

            rev2 = database.PutRevision(rev2, rev1.GetRevId(), false, status);
            Log.V(Tag, "Updated " + rev1);
            NUnit.Framework.Assert.AreEqual(rev1.GetDocId(), rev2.GetDocId());
            NUnit.Framework.Assert.IsTrue(rev2.GetRevId().StartsWith("2-"));
            //read it back
            readRev = database.GetDocumentWithIDAndRev(rev2.GetDocId(), null, EnumSet.NoneOf <
                                                           Database.TDContentOptions>());
            NUnit.Framework.Assert.IsNotNull(readRev);
            NUnit.Framework.Assert.AreEqual(UserProperties(readRev.GetProperties()), UserProperties
                                                (body.GetProperties()));
            // Try to update the first rev, which should fail:
            bool gotExpectedError = false;

            try
            {
                database.PutRevision(rev2input, rev1.GetRevId(), false, status);
            }
            catch (CouchbaseLiteException e)
            {
                gotExpectedError = e.GetCBLStatus().GetCode() == Status.Conflict;
            }
            NUnit.Framework.Assert.IsTrue(gotExpectedError);
            // Check the changes feed, with and without filters:
            RevisionList changes = database.ChangesSince(0, null, null);

            Log.V(Tag, "Changes = " + changes);
            NUnit.Framework.Assert.AreEqual(1, changes.Count);
            changes = database.ChangesSince(0, null, new _ReplicationFilter_95());
            NUnit.Framework.Assert.AreEqual(1, changes.Count);
            changes = database.ChangesSince(0, null, new _ReplicationFilter_105());
            NUnit.Framework.Assert.AreEqual(0, changes.Count);
            // Delete it:
            RevisionInternal revD = new RevisionInternal(rev2.GetDocId(), null, true, database
                                                         );
            RevisionInternal revResult = null;

            gotExpectedError = false;
            try
            {
                revResult = database.PutRevision(revD, null, false, status);
            }
            catch (CouchbaseLiteException e)
            {
                gotExpectedError = e.GetCBLStatus().GetCode() == Status.Conflict;
            }
            NUnit.Framework.Assert.IsTrue(gotExpectedError);
            NUnit.Framework.Assert.IsNull(revResult);
            revD = database.PutRevision(revD, rev2.GetRevId(), false, status);
            NUnit.Framework.Assert.AreEqual(Status.Ok, status.GetCode());
            NUnit.Framework.Assert.AreEqual(revD.GetDocId(), rev2.GetDocId());
            NUnit.Framework.Assert.IsTrue(revD.GetRevId().StartsWith("3-"));
            // Delete nonexistent doc:
            RevisionInternal revFake = new RevisionInternal("fake", null, true, database);

            gotExpectedError = false;
            try
            {
                database.PutRevision(revFake, null, false, status);
            }
            catch (CouchbaseLiteException e)
            {
                gotExpectedError = e.GetCBLStatus().GetCode() == Status.NotFound;
            }
            NUnit.Framework.Assert.IsTrue(gotExpectedError);
            // Read it back (should fail):
            readRev = database.GetDocumentWithIDAndRev(revD.GetDocId(), null, EnumSet.NoneOf <
                                                           Database.TDContentOptions>());
            NUnit.Framework.Assert.IsNull(readRev);
            // Get Changes feed
            changes = database.ChangesSince(0, null, null);
            NUnit.Framework.Assert.IsTrue(changes.Count == 1);
            // Get Revision History
            IList <RevisionInternal> history = database.GetRevisionHistory(revD);

            NUnit.Framework.Assert.AreEqual(revD, history[0]);
            NUnit.Framework.Assert.AreEqual(rev2, history[1]);
            NUnit.Framework.Assert.AreEqual(rev1, history[2]);
        }
Example #3
0
        public void TestRevTree()
        {
            var rev           = new RevisionInternal("MyDocId", "4-foxy", false);
            var revProperties = new Dictionary <string, object>();

            revProperties.Put("_id", rev.GetDocId());
            revProperties.Put("_rev", rev.GetRevId());
            revProperties["message"] = "hi";
            rev.SetProperties(revProperties);

            var revHistory = new List <string>();

            revHistory.AddItem(rev.GetRevId());
            revHistory.AddItem("3-thrice");
            revHistory.AddItem("2-too");
            revHistory.AddItem("1-won");
            database.ForceInsert(rev, revHistory, null);
            Assert.AreEqual(1, database.DocumentCount);

            VerifyHistory(database, rev, revHistory);
            var conflict           = new RevisionInternal("MyDocId", "5-epsilon", false);
            var conflictProperties = new Dictionary <string, object>();

            conflictProperties.Put("_id", conflict.GetDocId());
            conflictProperties.Put("_rev", conflict.GetRevId());
            conflictProperties["message"] = "yo";
            conflict.SetProperties(conflictProperties);

            var conflictHistory = new List <string>();

            conflictHistory.AddItem(conflict.GetRevId());
            conflictHistory.AddItem("4-delta");
            conflictHistory.AddItem("3-gamma");
            conflictHistory.AddItem("2-too");
            conflictHistory.AddItem("1-won");
            database.ForceInsert(conflict, conflictHistory, null);
            Assert.AreEqual(1, database.DocumentCount);
            VerifyHistory(database, conflict, conflictHistory);

            // Add an unrelated document:
            var other           = new RevisionInternal("AnotherDocID", "1-ichi", false);
            var otherProperties = new Dictionary <string, object>();

            otherProperties["language"] = "jp";
            other.SetProperties(otherProperties);
            var otherHistory = new List <string>();

            otherHistory.AddItem(other.GetRevId());
            database.ForceInsert(other, otherHistory, null);

            // Fetch one of those phantom revisions with no body:
            var rev2 = database.GetDocument(rev.GetDocId(), "2-too",
                                            true);

            Assert.IsNull(rev2);

            // Make sure no duplicate rows were inserted for the common revisions:
            Assert.AreEqual(8, database.LastSequenceNumber);
            // Make sure the revision with the higher revID wins the conflict:
            var current = database.GetDocument(rev.GetDocId(), null,
                                               true);

            Assert.AreEqual(conflict, current);

            // Get the _changes feed and verify only the winner is in it:
            var options         = new ChangesOptions();
            var changes         = database.ChangesSince(0, options, null, null);
            var expectedChanges = new RevisionList();

            expectedChanges.AddItem(conflict);
            expectedChanges.AddItem(other);
            Assert.AreEqual(expectedChanges, changes);
            options.SetIncludeConflicts(true);
            changes         = database.ChangesSince(0, options, null, null);
            expectedChanges = new RevisionList();
            expectedChanges.AddItem(rev);
            expectedChanges.AddItem(conflict);
            expectedChanges.AddItem(other);
            var expectedChangesAlt = new RevisionList();

            expectedChangesAlt.AddItem(conflict);
            expectedChangesAlt.AddItem(rev);
            expectedChangesAlt.AddItem(other);
            Assert.IsTrue(expectedChanges.SequenceEqual(changes) || expectedChangesAlt.SequenceEqual(changes));
        }
Example #4
0
        public void TestRevTree()
        {
            var change = default(DocumentChange);

            database.Changed += (sender, args) =>
            {
                Assert.AreEqual(1, args.Changes.Count());
                Assert.IsNull(change, "Multiple notifications posted");
                change = args.Changes.First();
            };

            var rev           = new RevisionInternal("MyDocId", "4-4444".AsRevID(), false);
            var revProperties = new Dictionary <string, object>();

            revProperties.SetDocRevID(rev.DocID, rev.RevID);
            revProperties["message"] = "hi";
            rev.SetProperties(revProperties);

            var revHistory = new List <RevisionID>();

            revHistory.Add(rev.RevID);
            revHistory.Add("3-3333".AsRevID());
            revHistory.Add("2-2222".AsRevID());
            revHistory.Add("1-1111".AsRevID());
            database.ForceInsert(rev, revHistory, null);
            Assert.AreEqual(1, database.GetDocumentCount());
            VerifyRev(rev, revHistory);
            Assert.AreEqual(Announcement(database, rev, rev), change);
            Assert.IsFalse(change.IsConflict);

            // No-op ForceInsert of already-existing revision
            var lastSeq = database.GetLastSequenceNumber();

            database.ForceInsert(rev, revHistory, null);
            Assert.AreEqual(lastSeq, database.GetLastSequenceNumber());

            var conflict           = new RevisionInternal("MyDocId", "5-5555".AsRevID(), false);
            var conflictProperties = new Dictionary <string, object>();

            conflictProperties.SetDocRevID(conflict.DocID, conflict.RevID);
            conflictProperties["message"] = "yo";
            conflict.SetProperties(conflictProperties);

            var conflictHistory = new List <RevisionID>();

            conflictHistory.Add(conflict.RevID);
            conflictHistory.Add("4-4545".AsRevID());
            conflictHistory.Add("3-3030".AsRevID());
            conflictHistory.Add("2-2222".AsRevID());
            conflictHistory.Add("1-1111".AsRevID());
            change = null;
            database.ForceInsert(conflict, conflictHistory, null);
            Assert.AreEqual(1, database.GetDocumentCount());
            VerifyRev(conflict, conflictHistory);
            Assert.AreEqual(Announcement(database, conflict, conflict), change);
            Assert.IsTrue(change.IsConflict);

            // Add an unrelated document:
            var other           = new RevisionInternal("AnotherDocID", "1-1010".AsRevID(), false);
            var otherProperties = new Dictionary <string, object>();

            otherProperties["language"] = "jp";
            other.SetProperties(otherProperties);
            var otherHistory = new List <RevisionID>();

            otherHistory.Add(other.RevID);
            change = null;
            database.ForceInsert(other, otherHistory, null);
            Assert.AreEqual(Announcement(database, other, other), change);
            Assert.IsFalse(change.IsConflict);

            // Fetch one of those phantom revisions with no body:
            var rev2 = database.GetDocument(rev.DocID, "2-2222".AsRevID(),
                                            true);

            Assert.IsTrue(rev2.Missing);
            Assert.IsNull(rev2.GetBody());

            Assert.IsNull(database.GetDocument(rev.DocID, "666-6666".AsRevID(), true));

            // Make sure no duplicate rows were inserted for the common revisions:
            if (_storageType == StorageEngineTypes.SQLite)
            {
                Assert.AreEqual(8, database.GetLastSequenceNumber());
            }
            else
            {
                Assert.AreEqual(3, database.GetLastSequenceNumber());
            }
            // Make sure the revision with the higher revID wins the conflict:
            var current = database.GetDocument(rev.DocID, null,
                                               true);

            Assert.AreEqual(conflict, current);

            // Check that the list of conflicts is accurate
            var conflictingRevs = database.Storage.GetAllDocumentRevisions(rev.DocID, true, false);

            CollectionAssert.AreEqual(new[] { conflict, rev }, conflictingRevs);

            // Get the _changes feed and verify only the winner is in it:
            var options = new ChangesOptions();
            var changes = database.ChangesSince(0, options, null, null);

            CollectionAssert.AreEqual(new[] { conflict, other }, changes);
            options.IncludeConflicts = true;
            changes = database.ChangesSince(0, options, null, null);
            var expectedChanges = new RevisionList();

            expectedChanges.Add(rev);
            expectedChanges.Add(conflict);
            expectedChanges.Add(other);
            var expectedChangesAlt = new RevisionList();

            expectedChangesAlt.Add(conflict);
            expectedChangesAlt.Add(rev);
            expectedChangesAlt.Add(other);
            Assert.IsTrue(expectedChanges.SequenceEqual(changes) || expectedChangesAlt.SequenceEqual(changes));
        }