public void TestLoadRevisionBody() { var document = database.CreateDocument(); var properties = new Dictionary <string, object>(); properties["foo"] = "foo"; properties["bar"] = false; properties["_id"] = document.Id; document.PutProperties(properties); properties.SetRevID(document.CurrentRevisionId); Assert.IsNotNull(document.CurrentRevision); var revisionInternal = new RevisionInternal( document.Id, document.CurrentRevisionId.AsRevID(), false); database.LoadRevisionBody(revisionInternal); Assert.AreEqual(properties, revisionInternal.GetProperties()); revisionInternal.SetBody(null); // now lets purge the document, and then try to load the revision body again document.Purge(); var gotExpectedException = false; try { database.LoadRevisionBody(revisionInternal); } catch (CouchbaseLiteException e) { gotExpectedException |= e.CBLStatus.Code == StatusCode.NotFound; } Assert.IsTrue(gotExpectedException); }
public void TestPutDeletedDocument() { Document document = database.CreateDocument(); var properties = new Dictionary <string, object>(); properties["foo"] = "foo"; properties["bar"] = false; document.PutProperties(properties); Assert.IsNotNull(document.CurrentRevision); var docId = document.Id; properties.SetRevID(document.CurrentRevisionId); properties["_deleted"] = true; properties["mykey"] = "myval"; var newRev = document.PutProperties(properties); newRev.LoadProperties(); Assert.IsTrue(newRev.Properties.ContainsKey("mykey")); Assert.IsTrue(document.Deleted); var featchedDoc = database.GetExistingDocument(docId); Assert.IsNull(featchedDoc); var queryAllDocs = database.CreateAllDocumentsQuery(); var queryEnumerator = queryAllDocs.Run(); foreach (QueryRow row in queryEnumerator) { Assert.AreNotEqual(row.Document.Id, docId); } }
public void TestHistoryAfterDocDeletion() { var properties = new Dictionary <string, object>() { { "tag", 1 } }; var docId = "testHistoryAfterDocDeletion"; var doc = database.GetDocument(docId); Assert.AreEqual(docId, doc.Id); doc.PutProperties(properties); var revId = doc.CurrentRevisionId.AsRevID(); for (var i = 2; i < 6; i++) { properties["tag"] = i; properties.SetRevID(revId); doc.PutProperties(properties); revId = doc.CurrentRevisionId.AsRevID(); Assert.AreEqual(i, revId.Generation); Assert.AreEqual(docId, doc.Id); } // now delete the doc and clear it from the cache so we // make sure we are reading a fresh copy doc.Delete(); database.RemoveDocumentFromCache(doc); // get doc from db with same ID as before, and the current rev should be null since the // last update was a deletion var docPostDelete = database.GetDocument(docId); Assert.IsNull(docPostDelete.CurrentRevision); properties = new Dictionary <string, object>() { { "tag", 6 } }; var newRevision = docPostDelete.CreateRevision(); newRevision.SetProperties(properties); var newSavedRevision = newRevision.Save(); // make sure the current revision of doc matches the rev we just saved Assert.AreEqual(newSavedRevision, docPostDelete.CurrentRevision); // make sure the rev id is 7- Assert.IsTrue(docPostDelete.CurrentRevisionId.StartsWith("7-", StringComparison.Ordinal)); }
public void TestLoadRevisionBody() { var document = database.CreateDocument(); var properties = new Dictionary<string, object>(); properties["foo"] = "foo"; properties["bar"] = false; properties["_id"] = document.Id; document.PutProperties(properties); properties.SetRevID(document.CurrentRevisionId); Assert.IsNotNull(document.CurrentRevision); var revisionInternal = new RevisionInternal( document.Id, document.CurrentRevisionId.AsRevID(), false); database.LoadRevisionBody(revisionInternal); Assert.AreEqual(properties, revisionInternal.GetProperties()); revisionInternal.SetBody(null); // now lets purge the document, and then try to load the revision body again document.Purge(); var gotExpectedException = false; try { database.LoadRevisionBody(revisionInternal); } catch (CouchbaseLiteException e) { gotExpectedException |= e.CBLStatus.Code == StatusCode.NotFound; } Assert.IsTrue(gotExpectedException); }
public void TestPutDeletedDocument() { Document document = database.CreateDocument(); var properties = new Dictionary<string, object>(); properties["foo"] = "foo"; properties["bar"] = false; document.PutProperties(properties); Assert.IsNotNull(document.CurrentRevision); var docId = document.Id; properties.SetRevID(document.CurrentRevisionId); properties["_deleted"] = true; properties["mykey"] = "myval"; var newRev = document.PutProperties(properties); newRev.LoadProperties(); Assert.IsTrue(newRev.Properties.ContainsKey("mykey")); Assert.IsTrue(document.Deleted); var featchedDoc = database.GetExistingDocument(docId); Assert.IsNull(featchedDoc); var queryAllDocs = database.CreateAllDocumentsQuery(); var queryEnumerator = queryAllDocs.Run(); foreach(QueryRow row in queryEnumerator) { Assert.AreNotEqual(row.Document.Id, docId); } }
public void TestHistoryAfterDocDeletion() { var properties = new Dictionary<string, object>() { {"tag", 1} }; var docId = "testHistoryAfterDocDeletion"; var doc = database.GetDocument(docId); Assert.AreEqual(docId, doc.Id); doc.PutProperties(properties); var revId = doc.CurrentRevisionId.AsRevID(); for (var i = 2; i < 6; i++) { properties["tag"] = i; properties.SetRevID(revId); doc.PutProperties(properties); revId = doc.CurrentRevisionId.AsRevID(); Assert.AreEqual(i, revId.Generation); Assert.AreEqual(docId, doc.Id); } // now delete the doc and clear it from the cache so we // make sure we are reading a fresh copy doc.Delete(); database.RemoveDocumentFromCache(doc); // get doc from db with same ID as before, and the current rev should be null since the // last update was a deletion var docPostDelete = database.GetDocument(docId); Assert.IsNull(docPostDelete.CurrentRevision); properties = new Dictionary<string, object>() { { "tag", 6 } }; var newRevision = docPostDelete.CreateRevision(); newRevision.SetProperties(properties); var newSavedRevision = newRevision.Save(); // make sure the current revision of doc matches the rev we just saved Assert.AreEqual(newSavedRevision, docPostDelete.CurrentRevision); // make sure the rev id is 7- Assert.IsTrue(docPostDelete.CurrentRevisionId.StartsWith("7-", StringComparison.Ordinal)); }
private void SaveLastSequence(SaveLastSequenceCompletionBlock completionHandler) { if (!lastSequenceChanged) { if (completionHandler != null) { completionHandler(); } return; } if (_savingCheckpoint) { // If a save is already in progress, don't do anything. (The completion block will trigger // another save after the first one finishes.) Task.Delay(500).ContinueWith(t => SaveLastSequence(completionHandler)); return; } lastSequenceChanged = false; var lastSequence = LastSequence; Log.To.Sync.I(Tag, "{0} checkpointing sequence={1}", this, lastSequence); var body = new Dictionary<String, Object>(); if (_remoteCheckpoint != null) { foreach (var pair in _remoteCheckpoint) { body[pair.Key] = pair.Value; } } body["lastSequence"] = lastSequence; var remoteCheckpointDocID = RemoteCheckpointDocID(); if (String.IsNullOrEmpty(remoteCheckpointDocID)) { Log.To.Sync.W(Tag, "remoteCheckpointDocID is null for {0}, aborting SaveLastSequence", this); if (completionHandler != null) { completionHandler(); } return; } _savingCheckpoint = true; var message = _remoteSession.SendAsyncRequest(HttpMethod.Put, "/_local/" + remoteCheckpointDocID, body, (result, e) => { _savingCheckpoint = false; if (e != null) { switch (GetStatusFromError(e)) { case StatusCode.NotFound: Log.To.Sync.I(Tag, "Got 404 from _local, ignoring..."); _remoteCheckpoint = null; break; case StatusCode.Conflict: Log.To.Sync.I(Tag, "Got 409 from _local, retrying..."); RefreshRemoteCheckpointDoc(); break; default: Log.To.Sync.W(Tag, String.Format("Unable to save remote checkpoint for {0}", _replicatorID), e); // TODO: On 401 or 403, and this is a pull, remember that remote // TODO: is read-only & don't attempt to read its checkpoint next time. break; } } else { var response = result.AsDictionary<string, object>(); var rev = response.GetCast<string>("rev"); if(rev != null) { body.SetRevID(rev); } _remoteCheckpoint = body; var localDb = LocalDatabase; if(localDb.Storage == null) { Log.To.Sync.I(Tag, "Database is null or closed, ignoring remote checkpoint response"); if(completionHandler != null) { completionHandler(); } return; } localDb.SetLastSequence(LastSequence, remoteCheckpointDocID); Log.To.Sync.I(Tag, "{0} saved remote checkpoint '{1}' (_rev={2})", this, lastSequence, rev); } if (completionHandler != null) { completionHandler (); } }, true); // This request should not be canceled when the replication is told to stop: if(message != null) { Task dummy; _remoteSession?._requests.TryRemove(message, out dummy); } }