summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/www/script/couch_tests.js35
-rw-r--r--src/couchdb/couch_db.hrl1
-rw-r--r--src/couchdb/couch_httpd_external.erl2
-rw-r--r--src/couchdb/couch_httpd_show.erl6
-rw-r--r--src/couchdb/couch_httpd_view.erl16
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.