/// <exception cref="System.Exception"></exception> public virtual void TestPruneRevsToMaxDepth() { IDictionary <string, object> properties = new Dictionary <string, object>(); properties.Put("testName", "testDatabaseCompaction"); properties.Put("tag", 1337); Document doc = CreateDocumentWithProperties(database, properties); SavedRevision rev = doc.GetCurrentRevision(); database.SetMaxRevTreeDepth(1); for (int i = 0; i < 10; i++) { IDictionary <string, object> properties2 = new Dictionary <string, object>(properties ); properties2.Put("tag", i); rev = rev.CreateRevision(properties2); } int numPruned = database.PruneRevsToMaxDepth(1); NUnit.Framework.Assert.AreEqual(9, numPruned); Document fetchedDoc = database.GetDocument(doc.GetId()); IList <SavedRevision> revisions = fetchedDoc.GetRevisionHistory(); NUnit.Framework.Assert.AreEqual(1, revisions.Count); numPruned = database.PruneRevsToMaxDepth(1); NUnit.Framework.Assert.AreEqual(0, numPruned); }
protected internal UnsavedRevision(Document document, SavedRevision parentRevision ) : base(document) { if (parentRevision == null) { parentRevID = null; } else { parentRevID = parentRevision.GetId(); } IDictionary <string, object> parentRevisionProperties; if (parentRevision == null) { parentRevisionProperties = null; } else { parentRevisionProperties = parentRevision.GetProperties(); } if (parentRevisionProperties == null) { properties = new Dictionary <string, object>(); properties.Put("_id", document.GetId()); if (parentRevID != null) { properties.Put("_rev", parentRevID); } } else { properties = new Dictionary <string, object>(parentRevisionProperties); } }
public override IList <SavedRevision> GetRevisionHistory() { // (Don't include self in the array, because this revision doesn't really exist yet) SavedRevision parent = GetParent(); return(parent != null?parent.GetRevisionHistory() : new AList <SavedRevision>()); }
protected internal UnsavedRevision(Document document, SavedRevision parentRevision ) : base(document) { if (parentRevision == null) { parentRevID = null; } else { parentRevID = parentRevision.GetId(); } IDictionary<string, object> parentRevisionProperties; if (parentRevision == null) { parentRevisionProperties = null; } else { parentRevisionProperties = parentRevision.GetProperties(); } if (parentRevisionProperties == null) { properties = new Dictionary<string, object>(); properties.Put("_id", document.GetId()); if (parentRevID != null) { properties.Put("_rev", parentRevID); } } else { properties = new Dictionary<string, object>(parentRevisionProperties); } }
/// <summary>https://github.com/couchbase/couchbase-lite-java-core/issues/164</summary> /// <exception cref="System.Exception"></exception> public virtual void TestRevisionIdEquivalentRevisions() { // two revisions with the same content and the same json // should have the exact same revision id, because their content // will have an identical hash IDictionary <string, object> properties = new Dictionary <string, object>(); properties.Put("testName", "testCreateRevisions"); properties.Put("tag", 1337); IDictionary <string, object> properties2 = new Dictionary <string, object>(); properties2.Put("testName", "testCreateRevisions"); properties2.Put("tag", 1338); Document doc = database.CreateDocument(); UnsavedRevision newRev = doc.CreateRevision(); newRev.SetUserProperties(properties); SavedRevision rev1 = newRev.Save(); UnsavedRevision newRev2a = rev1.CreateRevision(); newRev2a.SetUserProperties(properties2); SavedRevision rev2a = newRev2a.Save(); UnsavedRevision newRev2b = rev1.CreateRevision(); newRev2b.SetUserProperties(properties2); SavedRevision rev2b = newRev2b.Save(true); NUnit.Framework.Assert.AreEqual(rev2a.GetId(), rev2b.GetId()); }
public void TestJsFilterFunctionWithParameters() { var c = new JSFilterCompiler(); var filterBlock = c.CompileFilter("function(doc,req){return doc.name == req.name;}", "javascript"); Assert.IsNotNull(filterBlock); var filterParams = new Dictionary <string, object> { { "name", "jim" } }; var document = new Document(null, "doc1"); var rev = new RevisionInternal(new Dictionary <string, object> { { "_id", "doc1" }, { "_rev", "1-aa" }, { "foo", 666 } }); var savedRev = new SavedRevision(document, rev); Assert.IsFalse(filterBlock(savedRev, filterParams)); rev = new RevisionInternal(new Dictionary <string, object> { { "_id", "doc1" }, { "_rev", "1-aa" }, { "name", "bob" } }); savedRev = new SavedRevision(document, rev); Assert.IsFalse(filterBlock(savedRev, filterParams)); rev = new RevisionInternal(new Dictionary <string, object> { { "_id", "doc1" }, { "_rev", "1-aa" }, { "name", "jim" } }); savedRev = new SavedRevision(document, rev); Assert.IsTrue(filterBlock(savedRev, filterParams)); }
internal void RevisionAdded(DocumentChange documentChange) { RevisionInternal rev = documentChange.GetWinningRevision(); if (rev == null) { return; } // current revision didn't change if (currentRevision != null && !rev.GetRevId().Equals(currentRevision.GetId())) { if (!rev.IsDeleted()) { currentRevision = new SavedRevision(this, rev); } else { currentRevision = null; } } foreach (Document.ChangeListener listener in changeListeners) { listener.Changed(new Document.ChangeEvent(this, documentChange)); } }
/// <summary>Saves a new revision by letting the caller update the existing properties. /// </summary> /// <remarks> /// Saves a new revision by letting the caller update the existing properties. /// This method handles conflicts by retrying (calling the block again). /// The DocumentUpdater implementation should modify the properties of the new revision and return YES to save or /// NO to cancel. Be careful: the DocumentUpdater can be called multiple times if there is a conflict! /// </remarks> /// <param name="updateDelegate"> /// the callback DocumentUpdater implementation. Will be called on each /// attempt to save. Should update the given revision's properties and then /// return YES, or just return NO to cancel. /// </param> /// <returns>The new saved revision, or null on error or cancellation.</returns> /// <exception cref="CouchbaseLiteException">CouchbaseLiteException</exception> /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception> public SavedRevision Update(UpdateDelegate updateDelegate) { Debug.Assert(updateDelegate != null); var lastErrorCode = StatusCode.Unknown; do { UnsavedRevision newRev = CreateRevision(); if (!updateDelegate(newRev)) { break; } try { SavedRevision savedRev = newRev.Save(); if (savedRev != null) { return(savedRev); } } catch (CouchbaseLiteException e) { lastErrorCode = e.GetCBLStatus().GetCode(); } }while (lastErrorCode == StatusCode.Conflict); return(null); }
public SavedRevision Update(Document.DocumentUpdater updater) { int lastErrorCode = Status.Unknown; do { UnsavedRevision newRev = CreateRevision(); if (updater.Update(newRev) == false) { break; } try { SavedRevision savedRev = newRev.Save(); if (savedRev != null) { return(savedRev); } } catch (CouchbaseLiteException e) { lastErrorCode = e.GetCBLStatus().GetCode(); } }while (lastErrorCode == Status.Conflict); return(null); }
internal void RevisionAdded(DocumentChange documentChange) { var rev = documentChange.WinningRevision; if (rev == null) { return; } // current revision didn't change if (currentRevision != null && !rev.GetRevId().Equals(currentRevision.Id)) { currentRevision = new SavedRevision(this, rev); } var args = new DocumentChangeEventArgs { Change = documentChange, Source = this }; var changeEvent = Change; if (changeEvent != null) { changeEvent(this, args); } }
/// <exception cref="System.Exception"></exception> public virtual void TestCorrectWinningRevisionTiebreaker() { // Create a conflict on purpose Document doc = database.CreateDocument(); SavedRevision rev1 = doc.CreateRevision().Save(); SavedRevision rev2a = CreateRevisionWithRandomProps(rev1, false); SavedRevision rev2b = CreateRevisionWithRandomProps(rev1, true); // the tiebreaker will happen based on which rev hash has lexicographically higher sort order SavedRevision expectedWinner = null; if (Sharpen.Runtime.CompareOrdinal(rev2a.GetId(), rev2b.GetId()) > 0) { expectedWinner = rev2a; } else { if (Sharpen.Runtime.CompareOrdinal(rev2a.GetId(), rev2b.GetId()) < 0) { expectedWinner = rev2b; } } RevisionInternal revFound = database.GetDocumentWithIDAndRev(doc.GetId(), null, EnumSet .NoneOf <Database.TDContentOptions>()); NUnit.Framework.Assert.AreEqual(expectedWinner.GetId(), revFound.GetRevId()); }
public SavedRevision GetCurrentRevision() { if (currentRevision == null) { currentRevision = GetRevisionWithId(null); } return(currentRevision); }
public string GetCurrentRevisionId() { SavedRevision rev = GetCurrentRevision(); if (rev == null) { return(null); } return(rev.GetId()); }
private static SavedRevision CreateRevisionWithRandomProps(SavedRevision parentRev, Boolean allowConflict) { var properties = new Dictionary <string, object>(); properties["val"] = Misc.CreateGUID(); var unsavedRevision = parentRev.CreateRevision(); unsavedRevision.SetUserProperties(properties); return(unsavedRevision.Save(allowConflict)); }
/// <exception cref="System.Exception"></exception> public static SavedRevision CreateRevisionWithRandomProps(SavedRevision createRevFrom , bool allowConflict) { IDictionary <string, object> properties = new Dictionary <string, object>(); properties.Put(UUID.RandomUUID().ToString(), "val"); UnsavedRevision unsavedRevision = createRevFrom.CreateRevision(); unsavedRevision.SetUserProperties(properties); return(unsavedRevision.Save(allowConflict)); }
/// <exception cref="System.Exception"></exception> public static SavedRevision CreateRevisionWithRandomProps(SavedRevision createRevFrom, bool allowConflict) { var properties = new Dictionary <string, object>(); properties.Put(Misc.CreateGUID(), "val"); var unsavedRevision = createRevFrom.CreateRevision(); unsavedRevision.SetUserProperties(properties); return(unsavedRevision.Save(allowConflict)); }
public void TestResolveConflict() { var properties = new Dictionary <string, object>() { { "testName", "testCreateRevisions" }, { "tag", 1337 } }; // Create a conflict on purpose var doc = database.CreateDocument(); var newRev1 = doc.CreateRevision(); newRev1.SetUserProperties(properties); var rev1 = newRev1.Save(); var rev2a = CreateRevisionWithRandomProps(rev1, false); var rev2b = CreateRevisionWithRandomProps(rev1, true); SavedRevision winningRev = null; SavedRevision losingRev = null; if (doc.CurrentRevisionId.Equals(rev2a.Id)) { winningRev = rev2a; losingRev = rev2b; } else { winningRev = rev2b; losingRev = rev2a; } Assert.AreEqual(2, doc.ConflictingRevisions.Count()); Assert.AreEqual(2, doc.GetLeafRevisions(true).Count); // let's manually choose the losing rev as the winner. First, delete winner, which will // cause losing rev to be the current revision. var deleteRevision = winningRev.DeleteDocument(); Assert.AreEqual(1, doc.ConflictingRevisions.Count()); Assert.AreEqual(2, doc.GetLeafRevisions(true).Count); Assert.AreEqual(3, RevisionInternal.GenerationFromRevID(deleteRevision.Id)); Assert.AreEqual(losingRev.Id, doc.CurrentRevisionId); // Finally create a new revision rev3 based on losing rev var rev3 = CreateRevisionWithRandomProps(losingRev, true); Assert.AreEqual(rev3.Id, doc.CurrentRevisionId); Assert.AreEqual(1, doc.ConflictingRevisions.Count()); Assert.AreEqual(2, doc.GetLeafRevisions(true).Count); }
/// <summary>https://github.com/couchbase/couchbase-lite-android/issues/134</summary> /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception> /// <exception cref="System.IO.IOException"></exception> public virtual void TestGetAttachmentBodyUsingPrefetch() { // add a doc with an attachment Document doc = database.CreateDocument(); UnsavedRevision rev = doc.CreateRevision(); IDictionary <string, object> properties = new Dictionary <string, object>(); properties["foo"] = "bar"; rev.SetUserProperties(properties); byte[] attachBodyBytes = Sharpen.Runtime.GetBytesForString("attach body"); Attachment attachment = new Attachment(new ByteArrayInputStream(attachBodyBytes), "text/plain"); string attachmentName = "test_attachment.txt"; rev.AddAttachment(attachment, attachmentName); rev.Save(); // do query that finds that doc with prefetch View view = database.GetView("aview"); view.SetMapReduce((IDictionary <string, object> document, EmitDelegate emitter) => { string id = (string)document["_id"]; emitter.Emit(id, null); }, null, "1"); // try to get the attachment Query query = view.CreateQuery(); query.Prefetch = true; QueryEnumerator results = query.Run(); while (results.MoveNext()) { QueryRow row = results.Current; // This returns the revision just fine, but the sequence number // is set to 0. SavedRevision revision = row.Document.CurrentRevision; IList <string> attachments = revision.AttachmentNames; // This returns an Attachment object which looks ok, except again // its sequence number is 0. The metadata property knows about // the length and mime type of the attachment. It also says // "stub" -> "true". Attachment attachmentRetrieved = revision.GetAttachment(attachmentName); // This throws a CouchbaseLiteException with StatusCode.NOT_FOUND. InputStream @is = attachmentRetrieved.GetContent(); NUnit.Framework.Assert.IsNotNull(@is); byte[] attachmentDataRetrieved = TextUtils.Read(@is); string attachmentDataRetrievedString = Sharpen.Runtime.GetStringForBytes(attachmentDataRetrieved ); string attachBodyString = Sharpen.Runtime.GetStringForBytes(attachBodyBytes); NUnit.Framework.Assert.AreEqual(attachBodyString, attachmentDataRetrievedString); } }
internal void RevisionAdded(DocumentChange documentChange, bool notify) { var revId = documentChange.WinningRevisionId; if (revId == null) { return; // current revision didn't change } if (_currentRevisionKnown && (currentRevision == null || !revId.Equals(currentRevision.Id))) { var rev = documentChange.WinningRevisionIfKnown; if (rev == null) { ForgetCurrentRevision(); } else if (rev.Deleted) { currentRevision = null; } else { currentRevision = new SavedRevision(this, rev); } } if (!notify) { return; } var args = new DocumentChangeEventArgs { Change = documentChange, Source = this }; Log.To.TaskScheduling.V(Tag, "Scheduling Change callback..."); _eventContext.StartNew(() => { var changeEvent = _change; if (changeEvent != null) { Log.To.TaskScheduling.V(Tag, "Firing Change callback..."); changeEvent(this, args); } else { Log.To.TaskScheduling.V(Tag, "Change callback is null, not firing..."); } }); }
public void Changed(Database.ChangeEvent @event) { NUnit.Framework.Assert.AreEqual(1, @event.GetChanges().Count); DocumentChange change = @event.GetChanges()[0]; NUnit.Framework.Assert.AreEqual(DocumentId, change.GetDocumentId()); NUnit.Framework.Assert.AreEqual(rev.GetRevId(), change.GetRevisionId()); NUnit.Framework.Assert.IsTrue(change.IsCurrentRevision()); NUnit.Framework.Assert.IsFalse(change.IsConflict()); SavedRevision current = this._enclosing.database.GetDocument(change.GetDocumentId ()).GetCurrentRevision(); NUnit.Framework.Assert.AreEqual(rev.GetRevId(), current.GetId()); }
/// <exception cref="System.Exception"></exception> public virtual void TestCorrectWinningRevisionLongerBranch() { // Create a conflict on purpose Document doc = database.CreateDocument(); SavedRevision rev1 = doc.CreateRevision().Save(); SavedRevision rev2a = CreateRevisionWithRandomProps(rev1, false); SavedRevision rev2b = CreateRevisionWithRandomProps(rev1, true); SavedRevision rev3b = CreateRevisionWithRandomProps(rev2b, true); // rev3b should be picked as the winner since it has a longer branch SavedRevision expectedWinner = rev3b; RevisionInternal revFound = database.GetDocumentWithIDAndRev(doc.GetId(), null, EnumSet .NoneOf <Database.TDContentOptions>()); NUnit.Framework.Assert.AreEqual(expectedWinner.GetId(), revFound.GetRevId()); }
public SavedRevision GetRevision(string id) { if (currentRevision != null && id.Equals(currentRevision.GetId())) { return(currentRevision); } EnumSet <Database.TDContentOptions> contentOptions = EnumSet.NoneOf <Database.TDContentOptions >(); RevisionInternal revisionInternal = database.GetDocumentWithIDAndRev(GetId(), id, contentOptions); SavedRevision revision = null; revision = GetRevisionFromRev(revisionInternal); return(revision); }
public override bool Equals(object o) { bool result = false; if (o is SavedRevision) { SavedRevision other = (SavedRevision)o; if (document.GetId().Equals(other.GetDocument().GetId()) && GetId().Equals(other. GetId())) { result = true; } } return(result); }
/// <summary>https://github.com/couchbase/couchbase-lite-java-core/issues/106</summary> /// <exception cref="System.Exception"></exception> public virtual void TestResolveConflict() { IDictionary <string, object> properties = new Dictionary <string, object>(); properties.Put("testName", "testCreateRevisions"); properties.Put("tag", 1337); // Create a conflict on purpose Document doc = database.CreateDocument(); UnsavedRevision newRev1 = doc.CreateRevision(); newRev1.SetUserProperties(properties); SavedRevision rev1 = newRev1.Save(); SavedRevision rev2a = CreateRevisionWithRandomProps(rev1, false); SavedRevision rev2b = CreateRevisionWithRandomProps(rev1, true); SavedRevision winningRev = null; SavedRevision losingRev = null; if (doc.GetCurrentRevisionId().Equals(rev2a.GetId())) { winningRev = rev2a; losingRev = rev2b; } else { winningRev = rev2b; losingRev = rev2a; } NUnit.Framework.Assert.AreEqual(2, doc.GetConflictingRevisions().Count); NUnit.Framework.Assert.AreEqual(2, doc.GetLeafRevisions().Count); // let's manually choose the losing rev as the winner. First, delete winner, which will // cause losing rev to be the current revision. SavedRevision deleteRevision = winningRev.DeleteDocument(); IList <SavedRevision> conflictingRevisions = doc.GetConflictingRevisions(); NUnit.Framework.Assert.AreEqual(1, conflictingRevisions.Count); NUnit.Framework.Assert.AreEqual(2, doc.GetLeafRevisions().Count); NUnit.Framework.Assert.AreEqual(3, deleteRevision.GetGeneration()); NUnit.Framework.Assert.AreEqual(losingRev.GetId(), doc.GetCurrentRevision().GetId ()); // Finally create a new revision rev3 based on losing rev SavedRevision rev3 = CreateRevisionWithRandomProps(losingRev, true); NUnit.Framework.Assert.AreEqual(rev3.GetId(), doc.GetCurrentRevisionId()); IList <SavedRevision> conflictingRevisions1 = doc.GetConflictingRevisions(); NUnit.Framework.Assert.AreEqual(1, conflictingRevisions1.Count); NUnit.Framework.Assert.AreEqual(2, doc.GetLeafRevisions().Count); }
/// <exception cref="System.Exception"></exception> public virtual void TestWinningRevIDOfDoc() { IDictionary <string, object> properties = new Dictionary <string, object>(); properties.Put("testName", "testCreateRevisions"); properties.Put("tag", 1337); IDictionary <string, object> properties2a = new Dictionary <string, object>(); properties2a.Put("testName", "testCreateRevisions"); properties2a.Put("tag", 1338); IDictionary <string, object> properties2b = new Dictionary <string, object>(); properties2b.Put("testName", "testCreateRevisions"); properties2b.Put("tag", 1339); IList <bool> outIsDeleted = new AList <bool>(); IList <bool> outIsConflict = new AList <bool>(); // Create a conflict on purpose Document doc = database.CreateDocument(); UnsavedRevision newRev1 = doc.CreateRevision(); newRev1.SetUserProperties(properties); SavedRevision rev1 = newRev1.Save(); long docNumericId = database.GetDocNumericID(doc.GetId()); NUnit.Framework.Assert.IsTrue(docNumericId != 0); NUnit.Framework.Assert.AreEqual(rev1.GetId(), database.WinningRevIDOfDoc(docNumericId , outIsDeleted, outIsConflict)); NUnit.Framework.Assert.IsTrue(outIsConflict.Count == 0); outIsDeleted = new AList <bool>(); outIsConflict = new AList <bool>(); UnsavedRevision newRev2a = rev1.CreateRevision(); newRev2a.SetUserProperties(properties2a); SavedRevision rev2a = newRev2a.Save(); NUnit.Framework.Assert.AreEqual(rev2a.GetId(), database.WinningRevIDOfDoc(docNumericId , outIsDeleted, outIsConflict)); NUnit.Framework.Assert.IsTrue(outIsConflict.Count == 0); outIsDeleted = new AList <bool>(); outIsConflict = new AList <bool>(); UnsavedRevision newRev2b = rev1.CreateRevision(); newRev2b.SetUserProperties(properties2b); SavedRevision rev2b = newRev2b.Save(true); database.WinningRevIDOfDoc(docNumericId, outIsDeleted, outIsConflict); NUnit.Framework.Assert.IsTrue(outIsConflict.Count > 0); }
internal void LoadCurrentRevisionFrom(QueryRow row) { if (row.GetDocumentRevisionId() == null) { return; } string revId = row.GetDocumentRevisionId(); if (currentRevision == null || RevIdGreaterThanCurrent(revId)) { IDictionary <string, object> properties = row.GetDocumentProperties(); if (properties != null) { RevisionInternal rev = new RevisionInternal(properties, row.GetDatabase()); currentRevision = new SavedRevision(this, rev); } } }
internal void LoadCurrentRevisionFrom(QueryRow row) { if (row.DocumentRevisionId == null) { return; } var revId = row.DocumentRevisionId; if (currentRevision == null || RevIdGreaterThanCurrent(revId)) { var properties = row.DocumentProperties; if (properties != null) { var rev = new RevisionInternal(properties, row.Database); currentRevision = new SavedRevision(this, rev); } } }
public virtual IList <SavedRevision> GetConflictingRevisions() { Document doc = database.GetDocument(sourceDocumentId); IDictionary <string, object> valueTmp = (IDictionary <string, object>)value; IList <string> conflicts = (IList <string>)valueTmp.Get("_conflicts"); if (conflicts == null) { conflicts = new AList <string>(); } IList <SavedRevision> conflictingRevisions = new AList <SavedRevision>(); foreach (string conflictRevisionId in conflicts) { SavedRevision revision = doc.GetRevision(conflictRevisionId); conflictingRevisions.AddItem(revision); } return(conflictingRevisions); }
/// <summary>https://github.com/couchbase/couchbase-lite-java-core/issues/106</summary> /// <exception cref="System.Exception"></exception> public virtual void TestResolveConflict() { IDictionary <string, object> result; // Create a conflict on purpose Document doc = database.CreateDocument(); SavedRevision rev1 = doc.CreateRevision().Save(); SavedRevision rev2a = CreateRevisionWithRandomProps(rev1, false); SavedRevision rev2b = CreateRevisionWithRandomProps(rev1, true); SavedRevision winningRev = null; SavedRevision losingRev = null; if (doc.GetCurrentRevisionId().Equals(rev2a.GetId())) { winningRev = rev2a; losingRev = rev2b; } else { winningRev = rev2b; losingRev = rev2a; } NUnit.Framework.Assert.AreEqual(2, doc.GetConflictingRevisions().Count); NUnit.Framework.Assert.AreEqual(2, doc.GetLeafRevisions().Count); result = (IDictionary <string, object>)Send("GET", string.Format("/%s/%s?conflicts=true" , DefaultTestDb, doc.GetId()), Status.Ok, null); IList <string> conflicts = (IList)result.Get("_conflicts"); NUnit.Framework.Assert.AreEqual(1, conflicts.Count); string conflictingRevId = conflicts[0]; NUnit.Framework.Assert.AreEqual(losingRev.GetId(), conflictingRevId); long docNumericID = database.GetDocNumericID(doc.GetId()); NUnit.Framework.Assert.IsTrue(docNumericID != 0); NUnit.Framework.Assert.IsNotNull(database.GetDocument(doc.GetId())); Log.D(Tag, "docNumericID for " + doc.GetId() + " is: " + docNumericID); result = (IDictionary <string, object>)Send("DELETE", string.Format("/%s/%s?rev=%s" , DefaultTestDb, doc.GetId(), conflictingRevId), Status.Ok, null); result = (IDictionary <string, object>)Send("GET", string.Format("/%s/%s?conflicts=true" , DefaultTestDb, doc.GetId()), Status.Ok, null); conflicts = (IList)result.Get("_conflicts"); NUnit.Framework.Assert.AreEqual(0, conflicts.Count); }
/// <summary>https://github.com/couchbase/couchbase-lite-java-core/issues/164</summary> /// <exception cref="System.Exception"></exception> public virtual void TestRevisionIdDifferentRevisions() { // two revisions with different json should have different rev-id's // because their content will have a different hash (even though // they have the same generation number) IDictionary <string, object> properties = new Dictionary <string, object>(); properties.Put("testName", "testCreateRevisions"); properties.Put("tag", 1337); Document doc = database.CreateDocument(); UnsavedRevision newRev = doc.CreateRevision(); newRev.SetUserProperties(properties); SavedRevision rev1 = newRev.Save(); SavedRevision rev2a = CreateRevisionWithRandomProps(rev1, false); SavedRevision rev2b = CreateRevisionWithRandomProps(rev1, true); NUnit.Framework.Assert.AreNotSame(rev2a.GetId(), rev2b.GetId()); }
internal void LoadCurrentRevisionFrom(QueryRow row) { if (row.DocRevID == null) { return; } var revId = row.DocRevID; if (currentRevision == null || revId.CompareTo(CurrentRevisionId.AsRevID()) > 0) { ForgetCurrentRevision(); var rev = row.DocumentRevision; if (rev != null) { currentRevision = new SavedRevision(this, rev); _currentRevisionKnown = true; } } }
public void ValidateRevision(RevisionInternal newRev, RevisionInternal oldRev) { if (validations == null || validations.Count == 0) { return; } ValidationContextImpl context = new ValidationContextImpl(this, oldRev, newRev); SavedRevision publicRev = new SavedRevision(this, newRev); foreach (string validationName in validations.Keys) { Validator validation = GetValidation(validationName); validation.Validate(publicRev, context); if (context.GetRejectMessage() != null) { throw new CouchbaseLiteException(context.GetRejectMessage(), Status.Forbidden); } } }
internal UnsavedRevision(Document document, SavedRevision parentRevision): base(document) { if (parentRevision == null) ParentRevisionID = null; else ParentRevisionID = parentRevision.Id; IDictionary<String, Object> parentRevisionProperties; if (parentRevision == null) { parentRevisionProperties = null; } else { parentRevisionProperties = parentRevision.Properties; } if (parentRevisionProperties == null) { properties = new Dictionary<String, Object>(); properties["_id"] = document.Id; if (ParentRevisionID != null) { properties["_rev"] = ParentRevisionID; } } else { properties = new Dictionary<string, object>(parentRevisionProperties); } }
internal void LoadCurrentRevisionFrom(QueryRow row) { if (row.GetDocumentRevisionId() == null) { return; } string revId = row.GetDocumentRevisionId(); if (currentRevision == null || RevIdGreaterThanCurrent(revId)) { IDictionary<string, object> properties = row.GetDocumentProperties(); if (properties != null) { RevisionInternal rev = new RevisionInternal(properties, row.GetDatabase()); currentRevision = new SavedRevision(this, rev); } } }
/// <exception cref="System.Exception"></exception> public static SavedRevision CreateRevisionWithRandomProps(SavedRevision createRevFrom, bool allowConflict) { var properties = new Dictionary<string, object>(); properties.Put(Misc.CreateGUID(), "val"); var unsavedRevision = createRevFrom.CreateRevision(); unsavedRevision.SetUserProperties(properties); return unsavedRevision.Save(allowConflict); }
public void TestJsFilterFunctionWithParameters() { var c = new JSFilterCompiler(); var filterBlock = c.CompileFilter("function(doc,req){return doc.name == req.name;}", "javascript"); Assert.IsNotNull(filterBlock); var filterParams = new Dictionary<string, object> { { "name", "jim" } }; var document = new Document(null, "doc1"); var rev = new RevisionInternal(new Dictionary<string, object> { { "_id", "doc1" }, { "_rev", "1-aa" }, { "foo", 666 } }); var savedRev = new SavedRevision(document, rev); Assert.IsFalse(filterBlock(savedRev, filterParams)); rev = new RevisionInternal(new Dictionary<string, object> { { "_id", "doc1" }, { "_rev", "1-aa" }, { "name", "bob" } }); savedRev = new SavedRevision(document, rev); Assert.IsFalse(filterBlock(savedRev, filterParams)); rev = new RevisionInternal(new Dictionary<string, object> { { "_id", "doc1" }, { "_rev", "1-aa" }, { "name", "jim" } }); savedRev = new SavedRevision(document, rev); Assert.IsTrue(filterBlock(savedRev, filterParams)); }
internal void RevisionAdded(DocumentChange documentChange) { var rev = documentChange.WinningRevision; if (rev == null) { return; } // current revision didn't change if (currentRevision != null && !rev.GetRevId().Equals(currentRevision.Id)) { currentRevision = new SavedRevision(this, rev); } var args = new DocumentChangeEventArgs { Change = documentChange, Source = this } ; var changeEvent = Change; if (changeEvent != null) changeEvent(this, args); }
internal bool RunFilter(FilterDelegate filter, IDictionary<string, object> filterParams, RevisionInternal rev) { if (filter == null) { return true; } var publicRev = new SavedRevision(this, rev); return filter(publicRev, filterParams); }
public SavedRevision GetCurrentRevision() { if (currentRevision == null) { currentRevision = GetRevisionWithId(null); } return currentRevision; }
/// <summary>VALIDATION</summary> /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception> internal void ValidateRevision(RevisionInternal newRev, RevisionInternal oldRev, String parentRevId) { if (_validations == null || _validations.Count == 0) { return; } var publicRev = new SavedRevision(this, newRev); publicRev.ParentRevisionID = parentRevId; var context = new ValidationContext(this, oldRev, newRev); foreach (var validationName in _validations.Keys) { var validation = GetValidation(validationName); validation(publicRev, context); if (context.RejectMessage != null) { throw new CouchbaseLiteException(context.RejectMessage, StatusCode.Forbidden); } } }
public bool RunFilter(ReplicationFilter filter, IDictionary<string, object> paramsIgnored , RevisionInternal rev) { if (filter == null) { return true; } SavedRevision publicRev = new SavedRevision(this, rev); return filter.Filter(publicRev, null); }
public bool Filter(SavedRevision revision, IDictionary<string, object> @params) { return "not updated!".Equals(revision.GetProperties().Get("status")); }
public bool Filter(SavedRevision revision, IDictionary<string, object> @params) { return true; }
public void TestJsFilterFunction() { var c = new JSFilterCompiler(); var filterBlock = c.CompileFilter("function(doc,req){return doc.ok;}", "javascript"); Assert.IsNotNull(filterBlock); var document = new Document(null, "doc1"); var rev = new RevisionInternal(new Dictionary<string, object> { { "_id", "doc1" }, { "_rev", "1-aa" }, { "foo", 666 } }); var savedRev = new SavedRevision(document, rev); Assert.IsFalse(filterBlock(savedRev, null)); rev = new RevisionInternal(new Dictionary<string, object> { { "_id", "doc1" }, { "_rev", "1-aa" }, { "ok", false } }); savedRev = new SavedRevision(document, rev); Assert.IsFalse(filterBlock(savedRev, null)); rev = new RevisionInternal(new Dictionary<string, object> { { "_id", "doc1" }, { "_rev", "1-aa" }, { "ok", true } }); savedRev = new SavedRevision(document, rev); Assert.IsTrue(filterBlock(savedRev, null)); rev = new RevisionInternal(new Dictionary<string, object> { { "_id", "doc1" }, { "_rev", "1-aa" }, { "ok", "mais oui" } }); savedRev = new SavedRevision(document, rev); Assert.IsTrue(filterBlock(savedRev, null)); }
/// <summary>VALIDATION</summary> /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception> internal Status ValidateRevision(RevisionInternal newRev, RevisionInternal oldRev, String parentRevId) { var validations = Shared.GetValues("validation", Name); if (validations == null || validations.Count == 0) { return new Status(StatusCode.Ok); } var publicRev = new SavedRevision(this, newRev, parentRevId); var context = new ValidationContext(this, oldRev, newRev); Status status = new Status(StatusCode.Ok); foreach (var validationName in validations.Keys) { var validation = GetValidation(validationName); try { validation(publicRev, context); } catch(Exception e) { Log.E(TAG, String.Format("Validation block '{0}'", validationName), e); status.Code = StatusCode.Exception; break; } if (context.RejectMessage != null) { Log.D(TAG, "Failed update of {0}: {1}:{2} Old doc = {3}{2} New doc = {4}", oldRev, context.RejectMessage, Environment.NewLine, oldRev == null ? null : oldRev.GetProperties(), newRev.GetProperties()); status.Code = StatusCode.Forbidden; break; } } return status; }
public _Responder_1630(Document doc, SavedRevision savedRev) { this.doc = doc; this.savedRev = savedRev; }
internal void RevisionAdded(DocumentChange documentChange) { RevisionInternal rev = documentChange.GetWinningRevision(); if (rev == null) { return; } // current revision didn't change if (currentRevision != null && !rev.GetRevId().Equals(currentRevision.GetId())) { currentRevision = new SavedRevision(this, rev); } foreach (Document.ChangeListener listener in changeListeners) { listener.Changed(new Document.ChangeEvent(this, documentChange)); } }