summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Kocoloski <kocolosk@apache.org>2011-08-25 19:07:26 +0000
committerAdam Kocoloski <kocolosk@apache.org>2011-08-25 19:07:26 +0000
commit9472aff5d8caca9fb973a55bc5eccae2cfb63c1e (patch)
tree8b633261eca7d7f442a04eca231804c42b402b60
parent476b01cd4ae27d81b4831091f40ca278eb872160 (diff)
Do not suppress old revisions from _changes
Requests to '_changes?style=all_docs' with a 'since' parameter would suppress revisions of a document generated before the start of the feed. The assumption may have been that those revisions were seen by the client in a previous request to _changes, but this is not necessarily true if the client is resuming the feed after a partial download. The safe thing to do is to include all leaf revisions for each document in the feed. Thanks Bob Dionne for the test code. Closes COUCHDB-1256 git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1161702 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--share/www/script/test/changes.js26
-rw-r--r--src/couchdb/couch_db.erl16
2 files changed, 28 insertions, 14 deletions
diff --git a/share/www/script/test/changes.js b/share/www/script/test/changes.js
index ea22bfb3..284f1985 100644
--- a/share/www/script/test/changes.js
+++ b/share/www/script/test/changes.js
@@ -507,6 +507,32 @@ couchTests.changes = function(debug) {
CouchDB.request("GET", "/" + db.name + "/_changes");
TEquals(0, CouchDB.requestStats('httpd', 'clients_requesting_changes').current);
+ // COUCHDB-1256
+ T(db.deleteDb());
+ T(db.createDb());
+
+ T(db.save({"_id":"foo", "a" : 123}).ok);
+ T(db.save({"_id":"bar", "a" : 456}).ok);
+
+ options = {
+ headers: {"Content-Type": "application/json"},
+ body: JSON.stringify({"_rev":"1-cc609831f0ca66e8cd3d4c1e0d98108a", "a":456})
+ };
+ req = CouchDB.request("PUT", "/" + db.name + "/foo?new_edits=false", options);
+
+ req = CouchDB.request("GET", "/" + db.name + "/_changes?style=all_docs");
+ resp = JSON.parse(req.responseText);
+
+ TEquals(3, resp.last_seq);
+ TEquals(2, resp.results.length);
+
+ req = CouchDB.request("GET", "/" + db.name + "/_changes?style=all_docs&since=2");
+ resp = JSON.parse(req.responseText);
+
+ TEquals(3, resp.last_seq);
+ TEquals(1, resp.results.length);
+ TEquals(2, resp.results[0].changes.length);
+
// cleanup
db.deleteDb();
};
diff --git a/src/couchdb/couch_db.erl b/src/couchdb/couch_db.erl
index f919c72c..3d8395f4 100644
--- a/src/couchdb/couch_db.erl
+++ b/src/couchdb/couch_db.erl
@@ -947,20 +947,8 @@ enum_docs_reduce_to_count(Reds) ->
changes_since(Db, Style, StartSeq, Fun, Acc) ->
changes_since(Db, Style, StartSeq, Fun, [], Acc).
-changes_since(Db, Style, StartSeq, Fun, Options, Acc) ->
- Wrapper = fun(DocInfo, _Offset, Acc2) ->
- #doc_info{revs=Revs} = DocInfo,
- DocInfo2 =
- case Style of
- main_only ->
- DocInfo;
- all_docs ->
- % remove revs before the seq
- DocInfo#doc_info{revs=[RevInfo ||
- #rev_info{seq=RevSeq}=RevInfo <- Revs, StartSeq < RevSeq]}
- end,
- Fun(DocInfo2, Acc2)
- end,
+changes_since(Db, _Style, StartSeq, Fun, Options, Acc) ->
+ Wrapper = fun(DocInfo, _Offset, Acc2) -> Fun(DocInfo, Acc2) end,
{ok, _LastReduction, AccOut} = couch_btree:fold(Db#db.docinfo_by_seq_btree,
Wrapper, Acc, [{start_key, StartSeq + 1}] ++ Options),
{ok, AccOut}.