diff options
-rw-r--r-- | share/www/script/couch_tests.js | 9 | ||||
-rw-r--r-- | src/couchdb/couch_db_updater.erl | 14 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_db.erl | 16 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_view.erl | 13 |
4 files changed, 40 insertions, 12 deletions
diff --git a/share/www/script/couch_tests.js b/share/www/script/couch_tests.js index dbc70325..20d8733f 100644 --- a/share/www/script/couch_tests.js +++ b/share/www/script/couch_tests.js @@ -216,6 +216,13 @@ var tests = { // and on the deleted one, no doc T(all_seq.rows[2].value.deleted); T(!all_seq.rows[2].doc); + + // test the all docs collates sanely + db.save({_id: "Z", foo: "Z"}); + db.save({_id: "a", foo: "a"}); + + var rows = db.allDocs({startkey: "Z", endkey: "Z"}).rows; + T(rows.length == 1); }, // Do some edit conflict detection tests @@ -1166,7 +1173,7 @@ var tests = { T(db.bulkSave(makeDocs(1, numDocs + 1)).ok); // test that the _all_docs view returns correctly with keys - var results = db.allDocs({startkey:"_design%2F", endkey:"_design%2FZZZ"}); + var results = db.allDocs({startkey:"_design", endkey:"_design0"}); T(results.rows.length == 1); for (var loop = 0; loop < 2; loop++) { diff --git a/src/couchdb/couch_db_updater.erl b/src/couchdb/couch_db_updater.erl index 049a354e..94605a3c 100644 --- a/src/couchdb/couch_db_updater.erl +++ b/src/couchdb/couch_db_updater.erl @@ -14,6 +14,7 @@ -behaviour(gen_server). -export([btree_by_id_reduce/2,btree_by_seq_reduce/2]). +-export([less_docid/2]). -export([init/1,terminate/2,handle_call/3,handle_cast/2,code_change/3,handle_info/2]). -include("couch_db.hrl"). @@ -245,6 +246,12 @@ simple_upgrade_record(Old, New) -> lists:sublist(tuple_to_list(New), size(Old) + 1, size(New)-size(Old)), list_to_tuple(tuple_to_list(Old) ++ NewValuesTail). +% used for doc insertion, also for the PassedEndFun on all_docs view +less_docid(A, B) when A==B -> false; +less_docid(nil, _) -> true; % nil - special key sorts before all +less_docid({}, _) -> false; % {} -> special key sorts after all +less_docid(A, B) -> A < B. + init_db(DbName, Filepath, Fd, Header0) -> case element(2, Header0) of ?LATEST_DISK_VERSION -> ok; @@ -253,12 +260,7 @@ init_db(DbName, Filepath, Fd, Header0) -> Header = simple_upgrade_record(Header0, #db_header{}), {ok, SummaryStream} = couch_stream:open(Header#db_header.summary_stream_state, Fd), ok = couch_stream:set_min_buffer(SummaryStream, 10000), - Less = - fun(A,B) when A==B -> false; - (nil, _) -> true; % nil - special key sorts before all - ({}, _) -> false; % {} -> special key sorts after all - (A, B) -> A < B - end, + Less = fun less_docid/2, {ok, IdBtree} = couch_btree:open(Header#db_header.fulldocinfo_by_id_btree_state, Fd, [{split, fun(X) -> btree_by_id_split(X) end}, diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl index df8eba80..5366da1e 100644 --- a/src/couchdb/couch_httpd_db.erl +++ b/src/couchdb/couch_httpd_db.erl @@ -268,6 +268,8 @@ all_docs_view(Req, Db, Keys) -> #view_query_args{ start_key = StartKey, start_docid = StartDocId, + end_key = EndKey, + end_docid = EndDocId, limit = Limit, skip = SkipCount, direction = Dir @@ -279,10 +281,22 @@ all_docs_view(Req, Db, Keys) -> end, FoldAccInit = {Limit, SkipCount, undefined, []}, + PassedEndFun = + case Dir of + fwd -> + fun(ViewKey, _ViewId) -> + couch_db_updater:less_docid(EndKey, ViewKey) + end; + rev-> + fun(ViewKey, _ViewId) -> + couch_db_updater:less_docid(ViewKey, EndKey) + end + end, + case Keys of nil -> FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs, Db, - TotalRowCount, fun couch_db:enum_docs_reduce_to_count/1), + TotalRowCount, fun couch_db:enum_docs_reduce_to_count/1, PassedEndFun), AdapterFun = fun(#full_doc_info{id=Id}=FullDocInfo, Offset, Acc) -> case couch_doc:to_doc_info(FullDocInfo) of #doc_info{deleted=false, rev=Rev} -> diff --git a/src/couchdb/couch_httpd_view.erl b/src/couchdb/couch_httpd_view.erl index de184de9..76b2f4af 100644 --- a/src/couchdb/couch_httpd_view.erl +++ b/src/couchdb/couch_httpd_view.erl @@ -15,7 +15,7 @@ -export([handle_view_req/2,handle_slow_view_req/2]). --export([parse_view_query/1,parse_view_query/2,make_view_fold_fun/5,finish_view_fold/3]). +-export([parse_view_query/1,parse_view_query/2,make_view_fold_fun/5, make_view_fold_fun/6,finish_view_fold/3]). -import(couch_httpd, [send_json/2,send_json/3,send_json/4,send_method_not_allowed/2, @@ -361,14 +361,13 @@ parse_view_query(Req, Keys, IsReduce) -> end. -make_view_fold_fun(Req, QueryArgs, Db, TotalViewCount, ReduceCountFun) -> +make_view_fold_fun(Req, QueryArgs, Db, + TotalViewCount, ReduceCountFun) -> #view_query_args{ end_key = EndKey, end_docid = EndDocId, - include_docs = IncludeDocs, direction = Dir } = QueryArgs, - PassedEndFun = case Dir of fwd -> @@ -380,6 +379,12 @@ make_view_fold_fun(Req, QueryArgs, Db, TotalViewCount, ReduceCountFun) -> couch_view:less_json([ViewKey, ViewId], [EndKey, EndDocId]) end end, + make_view_fold_fun(Req, QueryArgs, Db, TotalViewCount, ReduceCountFun, PassedEndFun). + +make_view_fold_fun(Req, QueryArgs, Db, TotalViewCount, ReduceCountFun, PassedEndFun) -> + #view_query_args{ + include_docs = IncludeDocs + } = QueryArgs, fun({{Key, DocId}, Value}, OffsetReds, {AccLimit, AccSkip, Resp, AccRevRows}) -> |