From 9e53f467f89bc3942f8795f6d07f61d3f5115f88 Mon Sep 17 00:00:00 2001 From: Paul Joseph Davis Date: Wed, 10 Nov 2010 19:44:05 +0000 Subject: Support the keys parameter in GET requests. You can now request a list of keys in the query string using a query string like: ?keys=["foo", "bar"] Your query string obviously needs to be properly escaped. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@1033676 13f79535-47bb-0310-9956-ffa450edef68 --- THANKS | 1 + share/www/script/couch.js | 2 +- share/www/script/test/list_views.js | 10 +++ share/www/script/test/view_multi_key_all_docs.js | 37 +++++++++++ share/www/script/test/view_multi_key_design.js | 78 ++++++++++++++++++++++++ src/couchdb/couch_httpd.erl | 11 +++- src/couchdb/couch_httpd_db.erl | 3 +- src/couchdb/couch_httpd_show.erl | 6 +- src/couchdb/couch_httpd_view.erl | 3 +- 9 files changed, 145 insertions(+), 6 deletions(-) diff --git a/THANKS b/THANKS index 3ed1534c..e6d7e87f 100644 --- a/THANKS +++ b/THANKS @@ -71,5 +71,6 @@ suggesting improvements or submitting changes. Some of these people are: * Klaus Trainer * Dale Harvey * Juuso Väänänen + * Jeff Zellner For a list of authors see the `AUTHORS` file. diff --git a/share/www/script/couch.js b/share/www/script/couch.js index 913f58fb..bcc19652 100644 --- a/share/www/script/couch.js +++ b/share/www/script/couch.js @@ -272,7 +272,7 @@ function CouchDB(name, httpHeaders) { for (var name in options) { if (!options.hasOwnProperty(name)) { continue; }; var value = options[name]; - if (name == "key" || name == "startkey" || name == "endkey") { + if (name == "key" || name == "keys" || name == "startkey" || name == "endkey") { value = toJSON(value); } buf.push(encodeURIComponent(name) + "=" + encodeURIComponent(value)); diff --git a/share/www/script/test/list_views.js b/share/www/script/test/list_views.js index 8578622a..e98a212e 100644 --- a/share/www/script/test/list_views.js +++ b/share/www/script/test/list_views.js @@ -327,6 +327,16 @@ couchTests.list_views = function(debug) { T(/FirstKey: 2/.test(xhr.responseText)); T(/LastKey: 7/.test(xhr.responseText)); + // multi-key fetch with GET + var xhr = CouchDB.request("GET", "/test_suite_db/_design/lists/_list/simpleForm/basicView" + + "?keys=[2,4,5,7]"); + + T(xhr.status == 200, "multi key"); + T(!(/Key: 1 /.test(xhr.responseText))); + T(/Key: 2/.test(xhr.responseText)); + T(/FirstKey: 2/.test(xhr.responseText)); + T(/LastKey: 7/.test(xhr.responseText)); + // no multi-key fetch allowed when group=false xhr = CouchDB.request("POST", "/test_suite_db/_design/lists/_list/simpleForm/withReduce?group=false", { body: '{"keys":[2,4,5,7]}' diff --git a/share/www/script/test/view_multi_key_all_docs.js b/share/www/script/test/view_multi_key_all_docs.js index 62e49665..1113be4d 100644 --- a/share/www/script/test/view_multi_key_all_docs.js +++ b/share/www/script/test/view_multi_key_all_docs.js @@ -25,24 +25,52 @@ couchTests.view_multi_key_all_docs = function(debug) { for(var i=0; i qs_value(Req, Key, Default) -> couch_util:get_value(Key, qs(Req), Default). +qs_json_value(Req, Key, Default) -> + case qs_value(Req, Key, Default) of + Default -> + Default; + Result -> + ?JSON_DECODE(Result) + end. + qs(#httpd{mochi_req=MochiReq}) -> MochiReq:parse_qs(). diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl index 77b891fe..2ef2fe4f 100644 --- a/src/couchdb/couch_httpd_db.erl +++ b/src/couchdb/couch_httpd_db.erl @@ -375,7 +375,8 @@ db_req(#httpd{path_parts=[_,<<"_purge">>]}=Req, _Db) -> send_method_not_allowed(Req, "POST"); db_req(#httpd{method='GET',path_parts=[_,<<"_all_docs">>]}=Req, Db) -> - all_docs_view(Req, Db, nil); + Keys = couch_httpd:qs_json_value(Req, "keys", nil), + all_docs_view(Req, Db, Keys); db_req(#httpd{method='POST',path_parts=[_,<<"_all_docs">>]}=Req, Db) -> couch_httpd:validate_ctype(Req, "application/json"), diff --git a/src/couchdb/couch_httpd_show.erl b/src/couchdb/couch_httpd_show.erl index fa8cd972..70dd82e1 100644 --- a/src/couchdb/couch_httpd_show.erl +++ b/src/couchdb/couch_httpd_show.erl @@ -153,12 +153,14 @@ send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) -> % view-list request with view and list from same design doc. handle_view_list_req(#httpd{method='GET', path_parts=[_, _, DesignName, _, ListName, ViewName]}=Req, Db, DDoc) -> - handle_view_list(Req, Db, DDoc, ListName, {DesignName, ViewName}, nil); + Keys = couch_httpd:qs_json_value(Req, "keys", nil), + handle_view_list(Req, Db, DDoc, ListName, {DesignName, ViewName}, Keys); % view-list request with view and list from different design docs. handle_view_list_req(#httpd{method='GET', path_parts=[_, _, _, _, ListName, ViewDesignName, ViewName]}=Req, Db, DDoc) -> - handle_view_list(Req, Db, DDoc, ListName, {ViewDesignName, ViewName}, nil); + Keys = couch_httpd:qs_json_value(Req, "keys", nil), + handle_view_list(Req, Db, DDoc, ListName, {ViewDesignName, ViewName}, Keys); handle_view_list_req(#httpd{method='GET'}=Req, _Db, _DDoc) -> send_error(Req, 404, <<"list_error">>, <<"Invalid path.">>); diff --git a/src/couchdb/couch_httpd_view.erl b/src/couchdb/couch_httpd_view.erl index 8829de02..63e737e8 100644 --- a/src/couchdb/couch_httpd_view.erl +++ b/src/couchdb/couch_httpd_view.erl @@ -57,7 +57,8 @@ design_doc_view(Req, Db, DName, ViewName, Keys) -> handle_view_req(#httpd{method='GET', path_parts=[_, _, DName, _, ViewName]}=Req, Db, _DDoc) -> - design_doc_view(Req, Db, DName, ViewName, nil); + Keys = couch_httpd:qs_json_value(Req, "keys", nil), + design_doc_view(Req, Db, DName, ViewName, Keys); handle_view_req(#httpd{method='POST', path_parts=[_, _, DName, _, ViewName]}=Req, Db, _DDoc) -> -- cgit v1.2.3