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]); }
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)); }
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)); }