Thanks Benoit! :) Cheers Jan --
On 13 Nov 2010, at 23:08, [email protected] wrote: > Author: benoitc > Date: Sat Nov 13 22:08:25 2010 > New Revision: 1034891 > > URL: http://svn.apache.org/viewvc?rev=1034891&view=rev > Log: > builtin changes filters fonctions: _doc_ids & _design. replace last > patch to get filtering on docids. > > Modified: > couchdb/trunk/share/www/script/test/changes.js > couchdb/trunk/src/couchdb/couch_changes.erl > 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=1034891&r1=1034890&r2=1034891&view=diff > ============================================================================== > --- couchdb/trunk/share/www/script/test/changes.js (original) > +++ couchdb/trunk/share/www/script/test/changes.js Sat Nov 13 22:08:25 2010 > @@ -407,28 +407,40 @@ couchTests.changes = function(debug) { > body: JSON.stringify({"doc_ids": ["something", "anotherthing", > "andmore"]}) > }; > > - var req = CouchDB.request("POST", "/test_suite_db/_changes", options); > + var req = CouchDB.request("POST", > "/test_suite_db/_changes?filter=_doc_ids", options); > var resp = JSON.parse(req.responseText); > T(resp.results.length === 0); > > T(db.save({"_id":"something", "bop" : "plankton"}).ok); > - var req = CouchDB.request("POST", "/test_suite_db/_changes", options); > + var req = CouchDB.request("POST", > "/test_suite_db/_changes?filter=_doc_ids", options); > var resp = JSON.parse(req.responseText); > T(resp.results.length === 1); > T(resp.results[0].id === "something"); > > T(db.save({"_id":"anotherthing", "bop" : "plankton"}).ok); > - var req = CouchDB.request("POST", "/test_suite_db/_changes", options); > + var req = CouchDB.request("POST", > "/test_suite_db/_changes?filter=_doc_ids", options); > var resp = JSON.parse(req.responseText); > T(resp.results.length === 2); > T(resp.results[0].id === "something"); > T(resp.results[1].id === "anotherthing"); > + > + var docids = JSON.stringify(["something", "anotherthing", "andmore"]), > + req = CouchDB.request("GET", > "/test_suite_db/_changes?filter=_doc_ids&doc_ids="+docids, options); > + var resp = JSON.parse(req.responseText); > + T(resp.results.length === 2); > + T(resp.results[0].id === "something"); > + T(resp.results[1].id === "anotherthing"); > + > + var req = CouchDB.request("GET", > "/test_suite_db/_changes?filter=_design"); > + var resp = JSON.parse(req.responseText); > + T(resp.results.length === 1); > + T(resp.results[0].id === "_design/erlang"); > > > if (!is_safari && xhr) { > // filter docids with continuous > xhr = CouchDB.newXhr(); > - xhr.open("POST", > "/test_suite_db/_changes?feed=continuous&timeout=500&since=7", true); > + xhr.open("POST", > "/test_suite_db/_changes?feed=continuous&timeout=500&since=7&filter=_doc_ids", > true); > xhr.setRequestHeader("Content-Type", "application/json"); > > xhr.send(options.body); > > Modified: couchdb/trunk/src/couchdb/couch_changes.erl > URL: > http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_changes.erl?rev=1034891&r1=1034890&r2=1034891&view=diff > ============================================================================== > --- couchdb/trunk/src/couchdb/couch_changes.erl (original) > +++ couchdb/trunk/src/couchdb/couch_changes.erl Sat Nov 13 22:08:25 2010 > @@ -78,33 +78,21 @@ get_callback_acc(Callback) when is_funct > {fun(Ev, Data, _) -> Callback(Ev, Data) end, ok}. > > %% @type Req -> #httpd{} | {json_req, JsonObj()} > -make_filter_fun({docids, Docids}, Style, _Req, _Db) -> > - fun(#doc_info{id=DocId, revs=[#rev_info{rev=Rev}|_]=Revs}) -> > - case lists:member(DocId, Docids) of > - true -> > - case Style of > - main_only -> > - [{[{<<"rev">>, couch_doc:rev_to_str(Rev)}]}]; > - all_docs -> > - [{[{<<"rev">>, couch_doc:rev_to_str(R)}]} > - || #rev_info{rev=R} <- Revs] > - end; > - _ -> [] > - end > - end; > - > make_filter_fun(FilterName, Style, Req, Db) -> > + FilterName1 = list_to_binary(FilterName), > + case FilterName1 of > + (<<"_", _/binary>>) -> > + builtin_filter_fun(FilterName1, Style, Req, Db); > + (_OSFun) -> > + os_filter_fun(FilterName, Style, Req, Db) > + end. > + > +os_filter_fun(FilterName, Style, Req, Db) -> > case [list_to_binary(couch_httpd:unquote(Part)) > || Part <- string:tokens(FilterName, "/")] of > [] -> > - fun(#doc_info{revs=[#rev_info{rev=Rev}|_]=Revs}) -> > - case Style of > - main_only -> > - [{[{<<"rev">>, couch_doc:rev_to_str(Rev)}]}]; > - all_docs -> > - [{[{<<"rev">>, couch_doc:rev_to_str(R)}]} > - || #rev_info{rev=R} <- Revs] > - end > + fun(#doc_info{revs=Revs}) -> > + builtin_results(Style, Revs) > end; > [DName, FName] -> > DesignId = <<"_design/", DName/binary>>, > @@ -135,6 +123,57 @@ make_filter_fun(FilterName, Style, Req, > "filter parameter must be of the form `designname/filtername`"}) > end. > > +builtin_filter_fun(<<"_doc_ids",_/binary>>, Style, > + #httpd{method='POST'}=Req, _Db) -> > + {Props} = couch_httpd:json_body_obj(Req), > + DocIds = couch_util:get_value(<<"doc_ids">>, Props, nil), > + filter_docids(DocIds, Style); > +builtin_filter_fun(<<"_doc_ids", _/binary>>, Style, > + #httpd{method='GET'}=Req, _Db) -> > + QS = couch_httpd:qs(Req), > + DocIds = case couch_util:get_value("doc_ids", QS, nil) of > + nil -> > + throw({bad_request, "`doc_ids` parameter is not set"}); > + DocIds1 -> > + ?JSON_DECODE(DocIds1) > + end, > + filter_docids(DocIds, Style); > +builtin_filter_fun(<<"_design", _/binary>>, Style, _Req, _Db) -> > + filter_designdoc(Style); > +builtin_filter_fun(_FilterName, _Style, _Req, _Db) -> > + throw({bad_request, > + "unkown builtin filter name"}). > + > +filter_docids(DocIds, Style) when is_list(DocIds)-> > + fun(#doc_info{id=DocId, revs=Revs}) -> > + case lists:member(DocId, DocIds) of > + true -> > + builtin_results(Style, Revs); > + _ -> [] > + end > + end; > +filter_docids(_, _) -> > + throw({bad_request, "`doc_ids` member is undefined or not a > + list."}). > + > +filter_designdoc(Style) -> > + fun(#doc_info{id=DocId, revs=Revs}) -> > + case DocId of > + <<"_design", _/binary>> -> > + builtin_results(Style, Revs); > + _ -> [] > + end > + end. > + > +builtin_results(Style, [#rev_info{rev=Rev}|_]=Revs) -> > + case Style of > + main_only -> > + [{[{<<"rev">>, couch_doc:rev_to_str(Rev)}]}]; > + all_docs -> > + [{[{<<"rev">>, couch_doc:rev_to_str(R)}]} > + || #rev_info{rev=R} <- Revs] > + end. > + > get_changes_timeout(Args, Callback) -> > #changes_args{ > heartbeat = Heartbeat, > > Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl > URL: > http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=1034891&r1=1034890&r2=1034891&view=diff > ============================================================================== > --- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original) > +++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Sat Nov 13 22:08:25 2010 > @@ -55,26 +55,15 @@ handle_request(#httpd{path_parts=[DbName > do_db_req(Req, Handler) > end. > > -handle_changes_req(#httpd{method='GET'}=Req, Db) -> > - handle_changes_req1(Req, Db, nil); > - > handle_changes_req(#httpd{method='POST'}=Req, Db) -> > couch_httpd:validate_ctype(Req, "application/json"), > - {Props} = couch_httpd:json_body_obj(Req), > - case couch_util:get_value(<<"doc_ids">>, Props, nil) of > - nil -> > - handle_changes_req1(Req, Db, nil); > - Docids when is_list(Docids) -> > - handle_changes_req1(Req, Db, Docids); > - _ -> > - throw({bad_request, "`docids` member must be a array."}) > - end; > - > + handle_changes_req1(Req, Db); > +handle_changes_req(#httpd{method='GET'}=Req, Db) -> > + handle_changes_req1(Req, Db); > handle_changes_req(#httpd{path_parts=[_,<<"_changes">>]}=Req, _Db) -> > send_method_not_allowed(Req, "GET,HEAD,POST"). > > - > -handle_changes_req1(Req, Db, Docids) -> > +handle_changes_req1(Req, Db) -> > MakeCallback = fun(Resp) -> > fun({change, Change, _}, "continuous") -> > send_chunk(Resp, [?JSON_ENCODE(Change) | "\n"]); > @@ -101,13 +90,8 @@ handle_changes_req1(Req, Db, Docids) -> > end > end, > ChangesArgs = parse_changes_query(Req), > - ChangesArgs1 = case Docids of > - nil -> ChangesArgs; > - _ -> ChangesArgs#changes_args{filter={docids, Docids}} > - end, > - > - ChangesFun = couch_changes:handle_changes(ChangesArgs1, Req, Db), > - WrapperFun = case ChangesArgs1#changes_args.feed of > + ChangesFun = couch_changes:handle_changes(ChangesArgs, Req, Db), > + WrapperFun = case ChangesArgs#changes_args.feed of > "normal" -> > {ok, Info} = couch_db:get_db_info(Db), > CurrentEtag = couch_httpd:make_etag(Info), > >
