/// <summary> /// Subscribes this object to the given database's <c>Changed</c> event for /// processing /// </summary> /// <param name="db">Db.</param> public void SubscribeToDatabase(Database db, long since, ChangesOptions options) { if (db == null) { return; } Db = db; IsAsync = true; _since = since; _options = options; if (ChangesFeedMode == ChangesFeedMode.LongPoll) { var currentChanges = Db.ChangesSince(since, options, ChangesFilter, FilterParams); IsAsync = !currentChanges.Any(); if (!IsAsync) { if (ChangesIncludeConflicts) { Response.JsonBody = new Body(DatabaseMethods.ResponseBodyForChanges(currentChanges, since, options.Limit, this)); } else { Response.JsonBody = new Body(DatabaseMethods.ResponseBodyForChanges(currentChanges, since, this)); } } else { Db.Changed += DatabaseChanged; } } }
// Processes a change in the subscribed database private void DatabaseChanged(object sender, DatabaseChangeEventArgs args) { foreach (var change in args.Changes) { var rev = change.AddedRevision; var winningRev = change.WinningRevision; if (!ChangesIncludeConflicts) { if (winningRev == null) { continue; // this change doesn't affect the winning rev ID, no need to send it } if (rev.Equals(winningRev)) { // This rev made a _different_ rev current, so substitute that one. // We need to emit the current sequence # in the feed, so put it in the rev. // This isn't correct internally (this is an old rev so it has an older sequence) // but consumers of the _changes feed don't care about the internal state. if (ChangesIncludeDocs) { _db.LoadRevisionBody(rev, DocumentContentOptions.None); } } } if (!_db.RunFilter(ChangesFilter, null, rev)) { continue; } if (ChangesFeedMode == ChangesFeedMode.LongPoll) { _changes.Add(rev); } else { Log.D(TAG, "Sending continuous change chunk"); var written = Response.SendContinuousLine(DatabaseMethods.ChangesDictForRev(rev, this), ChangesFeedMode); if (!written) { Terminate(); } } } if (ChangesFeedMode == ChangesFeedMode.LongPoll && _changes.Count > 0) { var body = new Body(DatabaseMethods.ResponseBodyForChanges(_changes, 0, this)); Response.WriteData(body.AsJson(), true); CouchbaseLiteRouter.ResponseFinished(this); } }
private void WriteChanges(RevisionList changes) { if (changes.Count > 0) { if (ChangesFeedMode == ChangesFeedMode.LongPoll) { var body = new Body(DatabaseMethods.ResponseBodyForChanges(changes, 0, this)); Response.WriteData(body.AsJson(), true); Terminate(); } else { foreach (var rev in changes) { var written = Response.SendContinuousLine(DatabaseMethods.ChangesDictForRev(rev, this), ChangesFeedMode); if (!written) { Terminate(); break; } } } } }