示例#1
0
		/// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
		public virtual void TestRevTree()
		{
			RevisionInternal rev = new RevisionInternal("MyDocId", "4-foxy", false, database);
			IDictionary<string, object> revProperties = new Dictionary<string, object>();
			revProperties.Put("_id", rev.GetDocId());
			revProperties.Put("_rev", rev.GetRevId());
			revProperties.Put("message", "hi");
			rev.SetProperties(revProperties);
			IList<string> revHistory = new AList<string>();
			revHistory.AddItem(rev.GetRevId());
			revHistory.AddItem("3-thrice");
			revHistory.AddItem("2-too");
			revHistory.AddItem("1-won");
			database.ForceInsert(rev, revHistory, null);
			NUnit.Framework.Assert.AreEqual(1, database.GetDocumentCount());
			VerifyHistory(database, rev, revHistory);
			RevisionInternal conflict = new RevisionInternal("MyDocId", "5-epsilon", false, database
				);
			IDictionary<string, object> conflictProperties = new Dictionary<string, object>();
			conflictProperties.Put("_id", conflict.GetDocId());
			conflictProperties.Put("_rev", conflict.GetRevId());
			conflictProperties.Put("message", "yo");
			conflict.SetProperties(conflictProperties);
			IList<string> conflictHistory = new AList<string>();
			conflictHistory.AddItem(conflict.GetRevId());
			conflictHistory.AddItem("4-delta");
			conflictHistory.AddItem("3-gamma");
			conflictHistory.AddItem("2-too");
			conflictHistory.AddItem("1-won");
			IList wasInConflict = new ArrayList();
			Database.ChangeListener listener = new _ChangeListener_84(wasInConflict);
			database.AddChangeListener(listener);
			database.ForceInsert(conflict, conflictHistory, null);
			NUnit.Framework.Assert.IsTrue(wasInConflict.Count > 0);
			database.RemoveChangeListener(listener);
			NUnit.Framework.Assert.AreEqual(1, database.GetDocumentCount());
			VerifyHistory(database, conflict, conflictHistory);
			// Add an unrelated document:
			RevisionInternal other = new RevisionInternal("AnotherDocID", "1-ichi", false, database
				);
			IDictionary<string, object> otherProperties = new Dictionary<string, object>();
			otherProperties.Put("language", "jp");
			other.SetProperties(otherProperties);
			IList<string> otherHistory = new AList<string>();
			otherHistory.AddItem(other.GetRevId());
			database.ForceInsert(other, otherHistory, null);
			// Fetch one of those phantom revisions with no body:
			RevisionInternal rev2 = database.GetDocumentWithIDAndRev(rev.GetDocId(), "2-too", 
				EnumSet.NoneOf<Database.TDContentOptions>());
			NUnit.Framework.Assert.AreEqual(rev.GetDocId(), rev2.GetDocId());
			NUnit.Framework.Assert.AreEqual("2-too", rev2.GetRevId());
			//Assert.assertNull(rev2.getContent());
			// Make sure no duplicate rows were inserted for the common revisions:
			NUnit.Framework.Assert.AreEqual(8, database.GetLastSequenceNumber());
			// Make sure the revision with the higher revID wins the conflict:
			RevisionInternal current = database.GetDocumentWithIDAndRev(rev.GetDocId(), null, 
				EnumSet.NoneOf<Database.TDContentOptions>());
			NUnit.Framework.Assert.AreEqual(conflict, current);
			// Get the _changes feed and verify only the winner is in it:
			ChangesOptions options = new ChangesOptions();
			RevisionList changes = database.ChangesSince(0, options, null);
			RevisionList expectedChanges = new RevisionList();
			expectedChanges.AddItem(conflict);
			expectedChanges.AddItem(other);
			NUnit.Framework.Assert.AreEqual(changes, expectedChanges);
			options.SetIncludeConflicts(true);
			changes = database.ChangesSince(0, options, null);
			expectedChanges = new RevisionList();
			expectedChanges.AddItem(rev);
			expectedChanges.AddItem(conflict);
			expectedChanges.AddItem(other);
			NUnit.Framework.Assert.AreEqual(changes, expectedChanges);
		}
示例#2
0
        internal IEnumerable<QueryRow> GetAllDocs(QueryOptions options)
        {
            // For regular all-docs, let storage do it all:
            if (options == null || options.AllDocsMode != AllDocsMode.BySequence) {
                return Storage.GetAllDocs(options);
            }

            if (options.Descending) {
                throw new CouchbaseLiteException("Descending all docs not implemented", StatusCode.NotImplemented);
            }

            ChangesOptions changesOpts = new ChangesOptions();
            changesOpts.SetLimit(options.Limit);
            changesOpts.SetIncludeDocs(options.IncludeDocs);
            changesOpts.SetIncludeConflicts(true);
            changesOpts.SetSortBySequence(true);

            long startSeq = KeyToSequence(options.StartKey, 1);
            long endSeq = KeyToSequence(options.EndKey, long.MaxValue);
            if (!options.InclusiveStart) {
                ++startSeq;
            }

            if (!options.InclusiveEnd) {
                --endSeq;
            }

            long minSeq = startSeq, maxSeq = endSeq;
            if (minSeq > maxSeq) {
                return null; // empty result
            }

            RevisionList revs = Storage.ChangesSince(minSeq - 1, changesOpts, null);
            if (revs == null) {
                return null;
            }

            var result = new List<QueryRow>();
            var revEnum = options.Descending ? revs.Reverse<RevisionInternal>() : revs;
            foreach (var rev in revEnum) {
                long seq = rev.GetSequence();
                if (seq < minSeq || seq > maxSeq) {
                    break;
                }

                var value = new NonNullDictionary<string, object> {
                    { "rev", rev.GetRevId() },
                    { "deleted", rev.IsDeleted() ? (object)true : null }
                };
                result.Add(new QueryRow(rev.GetDocId(), seq, rev.GetDocId(), value, rev, null));
            }

            return result;
        }
示例#3
0
        /// <exception cref="Couchbase.Lite.CouchbaseLiteException"></exception>
        public virtual void TestRevTree()
        {
            RevisionInternal             rev           = new RevisionInternal("MyDocId", "4-foxy", false, database);
            IDictionary <string, object> revProperties = new Dictionary <string, object>();

            revProperties.Put("_id", rev.GetDocId());
            revProperties.Put("_rev", rev.GetRevId());
            revProperties["message"] = "hi";
            rev.SetProperties(revProperties);
            IList <string> revHistory = new AList <string>();

            revHistory.AddItem(rev.GetRevId());
            revHistory.AddItem("3-thrice");
            revHistory.AddItem("2-too");
            revHistory.AddItem("1-won");
            database.ForceInsert(rev, revHistory, null);
            NUnit.Framework.Assert.AreEqual(1, database.DocumentCount);
            VerifyHistory(database, rev, revHistory);
            RevisionInternal conflict = new RevisionInternal("MyDocId", "5-epsilon", false, database
                                                             );
            IDictionary <string, object> conflictProperties = new Dictionary <string, object>();

            conflictProperties.Put("_id", conflict.GetDocId());
            conflictProperties.Put("_rev", conflict.GetRevId());
            conflictProperties["message"] = "yo";
            conflict.SetProperties(conflictProperties);
            IList <string> conflictHistory = new AList <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);
            NUnit.Framework.Assert.AreEqual(1, database.DocumentCount);
            VerifyHistory(database, conflict, conflictHistory);
            // Add an unrelated document:
            RevisionInternal other = new RevisionInternal("AnotherDocID", "1-ichi", false, database
                                                          );
            IDictionary <string, object> otherProperties = new Dictionary <string, object>();

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

            otherHistory.AddItem(other.GetRevId());
            database.ForceInsert(other, otherHistory, null);
            // Fetch one of those phantom revisions with no body:
            RevisionInternal rev2 = database.GetDocumentWithIDAndRev(rev.GetDocId(), "2-too",
                                                                     EnumSet.NoneOf <TDContentOptions>());

            NUnit.Framework.Assert.AreEqual(rev.GetDocId(), rev2.GetDocId());
            NUnit.Framework.Assert.AreEqual("2-too", rev2.GetRevId());
            //Assert.assertNull(rev2.getContent());
            // Make sure no duplicate rows were inserted for the common revisions:
            NUnit.Framework.Assert.AreEqual(8, database.GetLastSequenceNumber());
            // Make sure the revision with the higher revID wins the conflict:
            RevisionInternal current = database.GetDocumentWithIDAndRev(rev.GetDocId(), null,
                                                                        EnumSet.NoneOf <TDContentOptions>());

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

            expectedChanges.AddItem(conflict);
            expectedChanges.AddItem(other);
            NUnit.Framework.Assert.AreEqual(changes, expectedChanges);
            options.SetIncludeConflicts(true);
            changes         = database.ChangesSince(0, options, null);
            expectedChanges = new RevisionList();
            expectedChanges.AddItem(rev);
            expectedChanges.AddItem(conflict);
            expectedChanges.AddItem(other);
            NUnit.Framework.Assert.AreEqual(changes, expectedChanges);
        }
        public void TestRevTree()
        {
            var rev = new RevisionInternal("MyDocId", "4-foxy", false, database);
            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 AList<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, database);
            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 AList<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, database);
            var otherProperties = new Dictionary<string, object>();
            otherProperties["language"] = "jp";
            other.SetProperties(otherProperties);
            var otherHistory = new AList<string>();
            otherHistory.AddItem(other.GetRevId());
            database.ForceInsert(other, otherHistory, null);
            
            // Fetch one of those phantom revisions with no body:
            var rev2 = database.GetDocumentWithIDAndRev(rev.GetDocId(), "2-too", 
                DocumentContentOptions.None);
            Assert.AreEqual(rev.GetDocId(), rev2.GetDocId());
            Assert.AreEqual("2-too", rev2.GetRevId());
            
            // Make sure no duplicate rows were inserted for the common revisions:
            Assert.AreEqual(8, database.GetLastSequenceNumber());
            // Make sure the revision with the higher revID wins the conflict:
            var current = database.GetDocumentWithIDAndRev(rev.GetDocId(), null, 
                DocumentContentOptions.None);
            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);
            var expectedChanges = new RevisionList();
            expectedChanges.AddItem(conflict);
            expectedChanges.AddItem(other);
            Assert.AreEqual(changes, expectedChanges);
            options.SetIncludeConflicts(true);
            changes = database.ChangesSince(0, options, null);
            expectedChanges = new RevisionList();
            expectedChanges.AddItem(rev);
            expectedChanges.AddItem(conflict);
            expectedChanges.AddItem(other);
            Assert.AreEqual(changes, expectedChanges);
        }
示例#5
0
        internal override void BeginReplicating()
        {
            Log.D(TAG, "beginReplicating() called");

            // If we're still waiting to create the remote db, do nothing now. (This method will be
            // re-invoked after that request finishes; see maybeCreateRemoteDB() above.)
            if (_creatingTarget) {
                Log.D(TAG, "creatingTarget == true, doing nothing");
                return;
            }

            _pendingSequences = new SortedDictionary<long, int>();
            try {
                _maxPendingSequence = Int64.Parse(LastSequence);
            } catch (Exception e) {
                Log.W(TAG, "Error converting lastSequence: " + LastSequence + " to long. Using 0", e);
                _maxPendingSequence = 0;
            }

            if (Filter != null) {
                _filter = LocalDatabase.GetFilter(Filter);
            } else {
                // If not filter function was provided, but DocIds were
                // specified, then only push the documents listed in the
                // DocIds property. It is assumed that if the users
                // specified both a filter name and doc ids that their
                // custom filter function will handle that. This is 
                // consistent with the iOS behavior.
                if (DocIds != null && DocIds.Any()) {
                    _filter = (rev, filterParams) => DocIds.Contains(rev.Document.Id);
                }
            }

            if (Filter != null && _filter == null) {
                Log.W(TAG, string.Format("{0}: No ReplicationFilter registered for filter '{1}'; ignoring", this, Filter));
            }

            // Process existing changes since the last push:
            long lastSequenceLong = 0;
            if (LastSequence != null) {
                lastSequenceLong = long.Parse(LastSequence);
            }

            // Now listen for future changes (in continuous mode):
            // Note:  This needs to happen before adding the observer
            // or else there is a race condition.  
            // A document could be added between the call to
            // ChangesSince and adding the observer, which would result
            // in a document being skipped
            if (Continuous) {
                _observing = true;
                LocalDatabase.Changed += OnChanged;
            } 

            var options = new ChangesOptions();
            options.SetIncludeConflicts(true);
            var changes = LocalDatabase.ChangesSince(lastSequenceLong, options, _filter, FilterParams);
            if (changes.Count > 0) {
                Batcher.QueueObjects(changes);
                Batcher.Flush();
            }

            if (Continuous) {
                if (changes.Count == 0) {
                    FireTrigger(ReplicationTrigger.WaitingForChanges);
                }
            } else {
                if(changes.Count == 0) {
                    FireTrigger(ReplicationTrigger.StopGraceful);
                }
            }
        }
示例#6
0
        internal override void BeginReplicating()
        {
            Log.D(Tag, "beginReplicating() called");

            // If we're still waiting to create the remote db, do nothing now. (This method will be
            // re-invoked after that request finishes; see maybeCreateRemoteDB() above.)
            if (creatingTarget)
            {
                Log.D(Tag, "creatingTarget == true, doing nothing");
                return;
            }

            pendingSequences = new SortedSet<long>();
            try
            {
                maxPendingSequence = Int64.Parse(LastSequence);
            }
            catch (Exception e)
            {
                Log.W(Tag, "Error converting lastSequence: " + LastSequence + " to long. Using 0");
                maxPendingSequence = 0;
            }

            if (Filter != null)
            {
                filter = LocalDatabase.GetFilter(Filter);
            }

            if (Filter != null && filter == null)
            {
                Log.W(Tag, string.Format("{0}: No ReplicationFilter registered for filter '{1}'; ignoring"
                    , this, Filter));
            }

            // Process existing changes since the last push:
            long lastSequenceLong = 0;
            if (LastSequence != null)
            {
                lastSequenceLong = long.Parse(LastSequence);
            }

            var options = new ChangesOptions();
            options.SetIncludeConflicts(true);
            var changes = LocalDatabase.ChangesSince(lastSequenceLong, options, filter);
            if (changes.Count > 0)
            {
                Batcher.QueueObjects(changes);
                Batcher.Flush();
            }

            // Now listen for future changes (in continuous mode):
            if (continuous)
            {
                observing = true;
                LocalDatabase.Changed += OnChanged;
            }
        }
示例#7
0
		public override void BeginReplicating()
		{
			// If we're still waiting to create the remote db, do nothing now. (This method will be
			// re-invoked after that request finishes; see maybeCreateRemoteDB() above.)
			Log.D(Database.Tag, this + "|" + Sharpen.Thread.CurrentThread() + ": beginReplicating() called"
				);
			if (creatingTarget)
			{
				Log.D(Database.Tag, this + "|" + Sharpen.Thread.CurrentThread() + ": creatingTarget == true, doing nothing"
					);
				return;
			}
			else
			{
				Log.D(Database.Tag, this + "|" + Sharpen.Thread.CurrentThread() + ": creatingTarget != true, continuing"
					);
			}
			if (filterName != null)
			{
				filter = db.GetFilter(filterName);
			}
			if (filterName != null && filter == null)
			{
				Log.W(Database.Tag, string.Format("%s: No ReplicationFilter registered for filter '%s'; ignoring"
					, this, filterName));
			}
			// Process existing changes since the last push:
			long lastSequenceLong = 0;
			if (lastSequence != null)
			{
				lastSequenceLong = long.Parse(lastSequence);
			}
			ChangesOptions options = new ChangesOptions();
			options.SetIncludeConflicts(true);
			RevisionList changes = db.ChangesSince(lastSequenceLong, options, filter);
			if (changes.Count > 0)
			{
				batcher.QueueObjects(changes);
				batcher.Flush();
			}
			// Now listen for future changes (in continuous mode):
			if (continuous)
			{
				observing = true;
				db.AddChangeListener(this);
				Log.D(Database.Tag, this + "|" + Sharpen.Thread.CurrentThread() + ": pusher.beginReplicating() calling asyncTaskStarted()"
					);
				AsyncTaskStarted();
			}
		}
 public override void BeginReplicating()
 {
     Log.D(Log.TagSync, "%s: beginReplicating() called", this);
     // If we're still waiting to create the remote db, do nothing now. (This method will be
     // re-invoked after that request finishes; see maybeCreateRemoteDB() above.)
     if (creatingTarget)
     {
         Log.D(Log.TagSync, "%s: creatingTarget == true, doing nothing", this);
         return;
     }
     pendingSequences = Sharpen.Collections.SynchronizedSortedSet(new TreeSet<long>());
     try
     {
         maxPendingSequence = long.Parse(lastSequence);
     }
     catch (FormatException)
     {
         Log.W(Log.TagSync, "Error converting lastSequence: %s to long.  Using 0", lastSequence
             );
         maxPendingSequence = System.Convert.ToInt64(0);
     }
     if (filterName != null)
     {
         filter = db.GetFilter(filterName);
     }
     if (filterName != null && filter == null)
     {
         Log.W(Log.TagSync, "%s: No ReplicationFilter registered for filter '%s'; ignoring"
             , this, filterName);
     }
     // Process existing changes since the last push:
     long lastSequenceLong = 0;
     if (lastSequence != null)
     {
         lastSequenceLong = long.Parse(lastSequence);
     }
     ChangesOptions options = new ChangesOptions();
     options.SetIncludeConflicts(true);
     RevisionList changes = db.ChangesSince(lastSequenceLong, options, filter);
     if (changes.Count > 0)
     {
         batcher.QueueObjects(changes);
         batcher.Flush();
     }
     // Now listen for future changes (in continuous mode):
     if (continuous)
     {
         observing = true;
         db.AddChangeListener(this);
     }
 }
示例#9
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));
        }