Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 10297 invoked from network); 17 Apr 2011 13:27:43 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 17 Apr 2011 13:27:43 -0000 Received: (qmail 98831 invoked by uid 500); 17 Apr 2011 13:27:43 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 98797 invoked by uid 500); 17 Apr 2011 13:27:43 -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 98790 invoked by uid 99); 17 Apr 2011 13:27:43 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 17 Apr 2011 13:27:43 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.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; Sun, 17 Apr 2011 13:27:40 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id E7F6B23889F7; Sun, 17 Apr 2011 13:27:18 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1094143 - in /couchdb/trunk: THANKS share/www/script/test/bulk_docs.js src/couchdb/couch_httpd_db.erl Date: Sun, 17 Apr 2011 13:27:18 -0000 To: commits@couchdb.apache.org From: jan@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110417132718.E7F6B23889F7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jan Date: Sun Apr 17 13:27:18 2011 New Revision: 1094143 URL: http://svn.apache.org/viewvc?rev=1094143&view=rev Log: Return proper error message when 'docs' member is missing in _bulk_docs request bodies. Closes COUCHDB-910 Patch by Dipesh Patel. Modified: couchdb/trunk/THANKS couchdb/trunk/share/www/script/test/bulk_docs.js couchdb/trunk/src/couchdb/couch_httpd_db.erl Modified: couchdb/trunk/THANKS URL: http://svn.apache.org/viewvc/couchdb/trunk/THANKS?rev=1094143&r1=1094142&r2=1094143&view=diff ============================================================================== --- couchdb/trunk/THANKS (original) +++ couchdb/trunk/THANKS Sun Apr 17 13:27:18 2011 @@ -79,5 +79,6 @@ suggesting improvements or submitting ch * Thomas Vander Stichele * Felix Hummel * Tim Smith + * Dipesh Patel For a list of authors see the `AUTHORS` file. Modified: couchdb/trunk/share/www/script/test/bulk_docs.js URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/bulk_docs.js?rev=1094143&r1=1094142&r2=1094143&view=diff ============================================================================== --- couchdb/trunk/share/www/script/test/bulk_docs.js (original) +++ couchdb/trunk/share/www/script/test/bulk_docs.js Sun Apr 17 13:27:18 2011 @@ -97,4 +97,15 @@ couchTests.bulk_docs = function(debug) { var torem = {"_id": newdoc._id, "_rev": newdoc._rev, "_deleted": true}; results = db.bulkSave([update, torem]); T(results[0].error == "conflict" || results[1].error == "conflict"); + + + // verify that sending a request with no docs causes error thrown + var req = CouchDB.request("POST", "/test_suite_db/_bulk_docs", { + body: JSON.stringify({"doc": [{"foo":"bar"}]}) + }); + + T(req.status == 400 ); + result = JSON.parse(req.responseText); + T(result.error == "bad_request"); + T(result.reason == "Missing JSON list of 'docs'"); }; Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=1094143&r1=1094142&r2=1094143&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original) +++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Sun Apr 17 13:27:18 2011 @@ -23,7 +23,7 @@ send_response/4,start_json_response/2,start_json_response/3, send_chunk/2,last_chunk/1,end_json_response/1, start_chunked_response/3, absolute_uri/2, send/2, - start_response_length/4]). + start_response_length/4, send_error/4]). -record(doc_query_args, { options = [], @@ -283,61 +283,65 @@ db_req(#httpd{method='POST',path_parts=[ couch_stats_collector:increment({httpd, bulk_requests}), couch_httpd:validate_ctype(Req, "application/json"), {JsonProps} = couch_httpd:json_body_obj(Req), - DocsArray = couch_util:get_value(<<"docs">>, JsonProps), - case couch_httpd:header_value(Req, "X-Couch-Full-Commit") of - "true" -> - Options = [full_commit]; - "false" -> - Options = [delay_commit]; - _ -> - Options = [] - end, - case couch_util:get_value(<<"new_edits">>, JsonProps, true) of - true -> - Docs = lists:map( - fun({ObjProps} = JsonObj) -> - Doc = couch_doc:from_json_obj(JsonObj), - validate_attachment_names(Doc), - Id = case Doc#doc.id of - <<>> -> couch_uuids:new(); - Id0 -> Id0 - end, - case couch_util:get_value(<<"_rev">>, ObjProps) of - undefined -> - Revs = {0, []}; - Rev -> - {Pos, RevId} = couch_doc:parse_rev(Rev), - Revs = {Pos, [RevId]} + case couch_util:get_value(<<"docs">>, JsonProps) of + undefined -> + send_error(Req, 400, <<"bad_request">>, <<"Missing JSON list of 'docs'">>); + DocsArray -> + case couch_httpd:header_value(Req, "X-Couch-Full-Commit") of + "true" -> + Options = [full_commit]; + "false" -> + Options = [delay_commit]; + _ -> + Options = [] + end, + case couch_util:get_value(<<"new_edits">>, JsonProps, true) of + true -> + Docs = lists:map( + fun({ObjProps} = JsonObj) -> + Doc = couch_doc:from_json_obj(JsonObj), + validate_attachment_names(Doc), + Id = case Doc#doc.id of + <<>> -> couch_uuids:new(); + Id0 -> Id0 + end, + case couch_util:get_value(<<"_rev">>, ObjProps) of + undefined -> + Revs = {0, []}; + Rev -> + {Pos, RevId} = couch_doc:parse_rev(Rev), + Revs = {Pos, [RevId]} + end, + Doc#doc{id=Id,revs=Revs} end, - Doc#doc{id=Id,revs=Revs} + DocsArray), + Options2 = + case couch_util:get_value(<<"all_or_nothing">>, JsonProps) of + true -> [all_or_nothing|Options]; + _ -> Options end, - DocsArray), - Options2 = - case couch_util:get_value(<<"all_or_nothing">>, JsonProps) of - true -> [all_or_nothing|Options]; - _ -> Options - end, - case couch_db:update_docs(Db, Docs, Options2) of - {ok, Results} -> - % output the results - DocResults = lists:zipwith(fun update_doc_result_to_json/2, - Docs, Results), - send_json(Req, 201, DocResults); - {aborted, Errors} -> + case couch_db:update_docs(Db, Docs, Options2) of + {ok, Results} -> + % output the results + DocResults = lists:zipwith(fun update_doc_result_to_json/2, + Docs, Results), + send_json(Req, 201, DocResults); + {aborted, Errors} -> + ErrorsJson = + lists:map(fun update_doc_result_to_json/1, Errors), + send_json(Req, 417, ErrorsJson) + end; + false -> + Docs = lists:map(fun(JsonObj) -> + Doc = couch_doc:from_json_obj(JsonObj), + validate_attachment_names(Doc), + Doc + end, DocsArray), + {ok, Errors} = couch_db:update_docs(Db, Docs, Options, replicated_changes), ErrorsJson = lists:map(fun update_doc_result_to_json/1, Errors), - send_json(Req, 417, ErrorsJson) - end; - false -> - Docs = lists:map(fun(JsonObj) -> - Doc = couch_doc:from_json_obj(JsonObj), - validate_attachment_names(Doc), - Doc - end, DocsArray), - {ok, Errors} = couch_db:update_docs(Db, Docs, Options, replicated_changes), - ErrorsJson = - lists:map(fun update_doc_result_to_json/1, Errors), - send_json(Req, 201, ErrorsJson) + send_json(Req, 201, ErrorsJson) + end end; db_req(#httpd{path_parts=[_,<<"_bulk_docs">>]}=Req, _Db) -> send_method_not_allowed(Req, "POST");