diff options
-rw-r--r-- | share/www/script/couch_tests.js | 35 | ||||
-rw-r--r-- | src/couchdb/couch_db.hrl | 1 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_external.erl | 2 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_show.erl | 6 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_view.erl | 16 |
5 files changed, 52 insertions, 8 deletions
diff --git a/share/www/script/couch_tests.js b/share/www/script/couch_tests.js index bc4e067a..0ffee4cd 100644 --- a/share/www/script/couch_tests.js +++ b/share/www/script/couch_tests.js @@ -2796,9 +2796,33 @@ db.createDb(); } }) }), - qsParams: stringFun(function(head, row, req, row_number) { + qsParams: stringFun(function(head, row, req, row_info) { if(head) return {body: req.query.foo}; else return {body: "\n"}; + }), + stopIter: stringFun(function(head, row, req, row_info) { + if(head) { + return {body: "head"}; + } else if(row) { + if(row_info.row_number > 2) return {stop: true}; + return {body: " " + row_info.row_number}; + } else { + return {body: " tail"}; + } + }), + stopIter2: stringFun(function(head, row, req, row_info) { + return respondWith(req, { + html: function() { + if(head) { + return "head"; + } else if(row) { + if(row_info.row_number > 2) return {stop: true}; + return " " + row_info.row_number; + } else { + return " tail"; + } + } + }); }) } }; @@ -2870,6 +2894,15 @@ db.createDb(); // now with extra qs params xhr = CouchDB.request("GET", "/test_suite_db/_list/lists/qsParams/basicView?foo=blam"); T(xhr.responseText.match(/blam/)); + + + // aborting iteration + xhr = CouchDB.request("GET", "/test_suite_db/_list/lists/stopIter/basicView"); + T(xhr.responseText.match(/^head 0 1 2 tail$/)); + xhr = CouchDB.request("GET", "/test_suite_db/_list/lists/stopIter2/basicView"); + T(xhr.responseText.match(/^head 0 1 2 tail$/)); + + }, compact: function(debug) { diff --git a/src/couchdb/couch_db.hrl b/src/couchdb/couch_db.hrl index 1afea912..5b8b74ef 100644 --- a/src/couchdb/couch_db.hrl +++ b/src/couchdb/couch_db.hrl @@ -162,6 +162,7 @@ -record(extern_resp_args, { code = 200, + stop = false, data = <<>>, ctype = "application/json", headers = [] diff --git a/src/couchdb/couch_httpd_external.erl b/src/couchdb/couch_httpd_external.erl index 5f63ac0e..2e25705b 100644 --- a/src/couchdb/couch_httpd_external.erl +++ b/src/couchdb/couch_httpd_external.erl @@ -106,6 +106,8 @@ parse_external_response({Response}) -> Args; {<<"code">>, Value} -> Args#extern_resp_args{code=Value}; + {<<"stop">>, true} -> + Args#extern_resp_args{stop=true}; {<<"json">>, Value} -> Args#extern_resp_args{ data=?JSON_ENCODE(Value), diff --git a/src/couchdb/couch_httpd_show.erl b/src/couchdb/couch_httpd_show.erl index 2771a1c9..1da8fe98 100644 --- a/src/couchdb/couch_httpd_show.erl +++ b/src/couchdb/couch_httpd_show.erl @@ -127,13 +127,17 @@ output_map_list(Req, Lang, ListSrc, View, Db, QueryArgs) -> JsonResp = couch_query_servers:render_list_row(QueryServer, Req, Db2, {{Key, DocId}, Value}), #extern_resp_args{ + stop = StopIter, data = RowBody } = couch_httpd_external:parse_external_response(JsonResp), RowFront2 = case RowFront of nil -> []; _ -> RowFront end, - send_chunk(Resp, RowFront2 ++ binary_to_list(RowBody)) + case StopIter of + true -> stop; + _ -> send_chunk(Resp, RowFront2 ++ binary_to_list(RowBody)) + end end, FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs, Db, RowCount, diff --git a/src/couchdb/couch_httpd_view.erl b/src/couchdb/couch_httpd_view.erl index 7696bb0d..2674754e 100644 --- a/src/couchdb/couch_httpd_view.erl +++ b/src/couchdb/couch_httpd_view.erl @@ -416,13 +416,17 @@ make_view_fold_fun(Req, QueryArgs, Db, Offset = ReduceCountFun(OffsetReds), {ok, Resp2, BeginBody} = StartRespFun(Req, 200, TotalViewCount, Offset), - SendRowFun(Resp2, Db, - {{Key, DocId}, Value}, BeginBody, IncludeDocs), - {ok, {AccLimit - 1, 0, Resp2, AccRevRows}}; + case SendRowFun(Resp2, Db, + {{Key, DocId}, Value}, BeginBody, IncludeDocs) of + stop -> {stop, {AccLimit - 1, 0, Resp2, AccRevRows}}; + _ -> {ok, {AccLimit - 1, 0, Resp2, AccRevRows}} + end; {_, AccLimit, _, Resp} when (AccLimit > 0) -> - SendRowFun(Resp, Db, - {{Key, DocId}, Value}, nil, IncludeDocs), - {ok, {AccLimit - 1, 0, Resp, AccRevRows}} + case SendRowFun(Resp, Db, + {{Key, DocId}, Value}, nil, IncludeDocs) of + stop -> {stop, {AccLimit - 1, 0, Resp, AccRevRows}}; + _ -> {ok, {AccLimit - 1, 0, Resp, AccRevRows}} + end end end. |