Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 16267 invoked from network); 16 Sep 2009 06:36:22 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 16 Sep 2009 06:36:22 -0000 Received: (qmail 32836 invoked by uid 500); 16 Sep 2009 06:36:22 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 32756 invoked by uid 500); 16 Sep 2009 06:36:22 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 32747 invoked by uid 99); 16 Sep 2009 06:36:21 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 16 Sep 2009 06:36:21 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 16 Sep 2009 06:36:18 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 0399C2388909; Wed, 16 Sep 2009 06:35:57 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r815629 - in /couchdb/trunk: share/www/script/test/changes.js src/couchdb/couch_httpd_db.erl Date: Wed, 16 Sep 2009 06:35:56 -0000 To: commits@couchdb.apache.org From: jchris@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090916063557.0399C2388909@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jchris Date: Wed Sep 16 06:35:56 2009 New Revision: 815629 URL: http://svn.apache.org/viewvc?rev=815629&view=rev Log: add limit to _changes Modified: couchdb/trunk/share/www/script/test/changes.js couchdb/trunk/src/couchdb/couch_httpd_db.erl Modified: couchdb/trunk/share/www/script/test/changes.js URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/changes.js?rev=815629&r1=815628&r2=815629&view=diff ============================================================================== --- couchdb/trunk/share/www/script/test/changes.js (original) +++ couchdb/trunk/share/www/script/test/changes.js Wed Sep 16 06:35:56 2009 @@ -249,5 +249,7 @@ T(resp.results[0].id == docResp.id); }); - // todo implement adhoc filters... + req = CouchDB.request("GET", "/test_suite_db/_changes?limit=1"); + resp = JSON.parse(req.responseText); + TEquals(1, resp.results.length) }; Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=815629&r1=815628&r2=815629&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original) +++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Wed Sep 16 06:35:56 2009 @@ -83,6 +83,7 @@ {rev, Seq}; _Bad -> throw({bad_request, "descending must be true or false"}) end, + Limit = list_to_integer(couch_httpd:qs_value(Req, "limit", "1000000000000000")), ResponseType = couch_httpd:qs_value(Req, "feed", "normal"), if ResponseType == "continuous" orelse ResponseType == "longpoll" -> {ok, Resp} = start_json_response(Req, 200), @@ -100,7 +101,7 @@ {httpd, clients_requesting_changes}), try keep_sending_changes(Req, Resp, Db, StartSeq, <<"">>, Timeout, - TimeoutFun, ResponseType, FilterFun, EndFilterFun) + TimeoutFun, ResponseType, Limit, FilterFun, EndFilterFun) after couch_db_update_notifier:stop(Notify), get_rest_db_updated() % clean out any remaining update messages @@ -111,9 +112,9 @@ % send the etag {ok, Resp} = start_json_response(Req, 200, [{"Etag", CurrentEtag}]), start_sending_changes(Resp, ResponseType), - {ok, {_, LastSeq, _Prepend, _, _, _, _}} = + {ok, {_, LastSeq, _Prepend, _, _, _, _, _}} = send_changes(Req, Resp, Db, Dir, StartSeq, <<"">>, "normal", - FilterFun, EndFilterFun), + Limit, FilterFun, EndFilterFun), end_sending_changes(Resp, LastSeq, ResponseType) end) end; @@ -144,9 +145,9 @@ end_json_response(Resp). keep_sending_changes(#httpd{user_ctx=UserCtx,path_parts=[DbName|_]}=Req, Resp, - Db, StartSeq, Prepend, Timeout, TimeoutFun, ResponseType, Filter, End) -> - {ok, {_, EndSeq, Prepend2, _, _, _, _}} = send_changes(Req, Resp, Db, fwd, StartSeq, - Prepend, ResponseType, Filter, End), + Db, StartSeq, Prepend, Timeout, TimeoutFun, ResponseType, Limit, Filter, End) -> + {ok, {_, EndSeq, Prepend2, _, _, _, NewLimit, _}} = send_changes(Req, Resp, Db, fwd, StartSeq, + Prepend, ResponseType, Limit, Filter, End), couch_db:close(Db), if EndSeq > StartSeq, ResponseType == "longpoll" -> @@ -156,35 +157,37 @@ updated -> {ok, Db2} = couch_db:open(DbName, [{user_ctx, UserCtx}]), keep_sending_changes(Req, Resp, Db2, EndSeq, Prepend2, Timeout, - TimeoutFun, ResponseType, Filter, End); + TimeoutFun, ResponseType, NewLimit, Filter, End); stop -> end_sending_changes(Resp, EndSeq, ResponseType) end end. -changes_enumerator(DocInfos, {Db, _, _, FilterFun, Resp, "continuous", IncludeDocs}) -> +changes_enumerator(DocInfos, {Db, _, _, FilterFun, Resp, "continuous", Limit, IncludeDocs}) -> [#doc_info{id=Id, high_seq=Seq, revs=[#rev_info{deleted=Del,rev=Rev}|_]}|_] = DocInfos, Results0 = [FilterFun(DocInfo) || DocInfo <- DocInfos], Results = [Result || Result <- Results0, Result /= null], + Go = if Limit =< 1 -> stop; true -> ok end, case Results of [] -> - {ok, {Db, Seq, nil, FilterFun, Resp, "continuous", IncludeDocs}}; + {Go, {Db, Seq, nil, FilterFun, Resp, "continuous", Limit, IncludeDocs}}; _ -> send_chunk(Resp, [?JSON_ENCODE(changes_row(Db, Seq, Id, Del, Results, Rev, IncludeDocs)) |"\n"]), - {ok, {Db, Seq, nil, FilterFun, Resp, "continuous", IncludeDocs}} + {Go, {Db, Seq, nil, FilterFun, Resp, "continuous", Limit-1, IncludeDocs}} end; -changes_enumerator(DocInfos, {Db, _, Prepend, FilterFun, Resp, _, IncludeDocs}) -> +changes_enumerator(DocInfos, {Db, _, Prepend, FilterFun, Resp, _, Limit, IncludeDocs}) -> [#doc_info{id=Id, high_seq=Seq, revs=[#rev_info{deleted=Del,rev=Rev}|_]}|_] = DocInfos, Results0 = [FilterFun(DocInfo) || DocInfo <- DocInfos], Results = [Result || Result <- Results0, Result /= null], + Go = if Limit =< 1 -> stop; true -> ok end, case Results of [] -> - {ok, {Db, Seq, Prepend, FilterFun, Resp, nil, IncludeDocs}}; + {Go, {Db, Seq, Prepend, FilterFun, Resp, nil, Limit, IncludeDocs}}; _ -> send_chunk(Resp, [Prepend, ?JSON_ENCODE( changes_row(Db, Seq, Id, Del, Results, Rev, IncludeDocs))]), - {ok, {Db, Seq, <<",\n">>, FilterFun, Resp, nil, IncludeDocs}} + {Go, {Db, Seq, <<",\n">>, FilterFun, Resp, nil, Limit-1, IncludeDocs}} end. changes_row(Db, Seq, Id, Del, Results, Rev, true) -> @@ -196,14 +199,14 @@ deleted_item(true) -> [{deleted,true}]; deleted_item(_) -> []. -send_changes(Req, Resp, Db, Dir, StartSeq, Prepend, ResponseType, FilterFun, End) -> +send_changes(Req, Resp, Db, Dir, StartSeq, Prepend, ResponseType, Limit, FilterFun, End) -> Style = list_to_existing_atom( couch_httpd:qs_value(Req, "style", "main_only")), IncludeDocs = list_to_existing_atom( couch_httpd:qs_value(Req, "include_docs", "false")), try couch_db:changes_since(Db, Style, StartSeq, fun changes_enumerator/2, - [{dir, Dir}], {Db, StartSeq, Prepend, FilterFun, Resp, ResponseType, IncludeDocs}) + [{dir, Dir}], {Db, StartSeq, Prepend, FilterFun, Resp, ResponseType, Limit, IncludeDocs}) after End() end.