You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@couchdb.apache.org by Benoit Chesneau <bc...@gmail.com> on 2011/11/09 11:38:14 UTC
Re: [1/5] git commit: some refactoring in couch_httpd_db.erl
On Wed, Nov 9, 2011 at 11:07 AM, <ra...@apache.org> wrote:
> Updated Branches:
> refs/heads/master 866769f34 -> 7e3c69ba9
>
>
> some refactoring in couch_httpd_db.erl
>
> Fix COUCHDB-1277. These changes are largely for code clarity and
> conciseness, but have a few other nice effects as well.
>
> * Responses to documents created/modified via form data POST to /db/doc
> or copied with COPY should now include a Location header.
> * ?batch=ok updates should include a Location header.
> * Form data POST to /db/doc now includes an ETag response header.
> * ?batch=ok is now supported for COPY and POST /db/doc updates.
> * ?new_edits=false is now supported for more update paths. This change
> is likely not generally useful, but listed here for completeness.
>
>
> Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
> Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/7e3c69ba
> Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/7e3c69ba
> Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/7e3c69ba
>
> Branch: refs/heads/master
> Commit: 7e3c69ba951de7cfaa095145ba49c58d539a28ea
> Parents: e41d226
> Author: Randall Leeds <ra...@gmail.com>
> Authored: Thu Sep 8 20:44:09 2011 -0700
> Committer: Randall Leeds <ra...@apache.org>
> Committed: Wed Nov 9 02:06:52 2011 -0800
>
> ----------------------------------------------------------------------
> src/couchdb/couch_httpd_db.erl | 148 ++++++++++++----------------------
> 1 files changed, 52 insertions(+), 96 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/couchdb/blob/7e3c69ba/src/couchdb/couch_httpd_db.erl
> ----------------------------------------------------------------------
> diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
> index dad8705..4691143 100644
> --- a/src/couchdb/couch_httpd_db.erl
> +++ b/src/couchdb/couch_httpd_db.erl
> @@ -203,7 +203,7 @@ db_req(#httpd{method='GET',path_parts=[_DbName]}=Req, Db) ->
> {ok, DbInfo} = couch_db:get_db_info(Db),
> send_json(Req, {DbInfo});
>
> -db_req(#httpd{method='POST',path_parts=[DbName]}=Req, Db) ->
> +db_req(#httpd{method='POST',path_parts=[_DbName]}=Req, Db) ->
> couch_httpd:validate_ctype(Req, "application/json"),
> Doc = couch_doc:from_json_obj(couch_httpd:json_body(Req)),
> validate_attachment_names(Doc),
> @@ -214,33 +214,7 @@ db_req(#httpd{method='POST',path_parts=[DbName]}=Req, Db) ->
> Doc
> end,
> DocId = Doc2#doc.id,
> - case couch_httpd:qs_value(Req, "batch") of
> - "ok" ->
> - % async_batching
> - spawn(fun() ->
> - case catch(couch_db:update_doc(Db, Doc2, [])) of
> - {ok, _} -> ok;
> - Error ->
> - ?LOG_INFO("Batch doc error (~s): ~p",[DocId, Error])
> - end
> - end),
> -
> - send_json(Req, 202, [], {[
> - {ok, true},
> - {id, DocId}
> - ]});
> - _Normal ->
> - % normal
> - {ok, NewRev} = couch_db:update_doc(Db, Doc2, []),
> - DocUrl = absolute_uri(
> - Req, binary_to_list(<<"/",DbName/binary,"/", DocId/binary>>)),
> - send_json(Req, 201, [{"Location", DocUrl}], {[
> - {ok, true},
> - {id, DocId},
> - {rev, couch_doc:rev_to_str(NewRev)}
> - ]})
> - end;
> -
> + update_doc(Req, Db, DocId, Doc2);
>
> db_req(#httpd{path_parts=[_DbName]}=Req, _Db) ->
> send_method_not_allowed(Req, "DELETE,GET,HEAD,POST");
> @@ -673,29 +647,18 @@ db_doc_req(#httpd{method='POST'}=Req, Db, DocId) ->
> NewDoc = Doc#doc{
> atts = UpdatedAtts ++ OldAtts2
> },
> - {ok, NewRev} = couch_db:update_doc(Db, NewDoc, []),
> -
> - send_json(Req, 201, [{"ETag", "\"" ++ ?b2l(couch_doc:rev_to_str(NewRev)) ++ "\""}], {[
> - {ok, true},
> - {id, DocId},
> - {rev, couch_doc:rev_to_str(NewRev)}
> - ]});
> + update_doc(Req, Db, DocId, NewDoc);
>
> db_doc_req(#httpd{method='PUT'}=Req, Db, DocId) ->
> - #doc_query_args{
> - update_type = UpdateType
> - } = parse_doc_query(Req),
> couch_doc:validate_docid(DocId),
>
> - Loc = absolute_uri(Req, "/" ++ ?b2l(Db#db.name) ++ "/" ++ ?b2l(DocId)),
> - RespHeaders = [{"Location", Loc}],
> case couch_util:to_list(couch_httpd:header_value(Req, "Content-Type")) of
> ("multipart/related;" ++ _) = ContentType ->
> {ok, Doc0, WaitFun, Parser} = couch_doc:doc_from_multi_part_stream(
> ContentType, fun() -> receive_request_data(Req) end),
> Doc = couch_doc_from_req(Req, DocId, Doc0),
> try
> - Result = update_doc(Req, Db, DocId, Doc, RespHeaders, UpdateType),
> + Result = update_doc(Req, Db, DocId, Doc),
> WaitFun(),
> Result
> catch throw:Err ->
> @@ -704,28 +667,9 @@ db_doc_req(#httpd{method='PUT'}=Req, Db, DocId) ->
> throw(Err)
> end;
> _Else ->
> - case couch_httpd:qs_value(Req, "batch") of
> - "ok" ->
> - % batch
> - Doc = couch_doc_from_req(Req, DocId, couch_httpd:json_body(Req)),
> -
> - spawn(fun() ->
> - case catch(couch_db:update_doc(Db, Doc, [])) of
> - {ok, _} -> ok;
> - Error ->
> - ?LOG_INFO("Batch doc error (~s): ~p",[DocId, Error])
> - end
> - end),
> - send_json(Req, 202, [], {[
> - {ok, true},
> - {id, DocId}
> - ]});
> - _Normal ->
> - % normal
> - Body = couch_httpd:json_body(Req),
> - Doc = couch_doc_from_req(Req, DocId, Body),
> - update_doc(Req, Db, DocId, Doc, RespHeaders, UpdateType)
> - end
> + Body = couch_httpd:json_body(Req),
> + Doc = couch_doc_from_req(Req, DocId, Body),
> + update_doc(Req, Db, DocId, Doc)
> end;
>
> db_doc_req(#httpd{method='COPY'}=Req, Db, SourceDocId) ->
> @@ -738,12 +682,7 @@ db_doc_req(#httpd{method='COPY'}=Req, Db, SourceDocId) ->
> % open old doc
> Doc = couch_doc_open(Db, SourceDocId, SourceRev, []),
> % save new doc
> - {ok, NewTargetRev} = couch_db:update_doc(Db,
> - Doc#doc{id=TargetDocId, revs=TargetRevs}, []),
> - % respond
> - send_json(Req, 201,
> - [{"ETag", "\"" ++ ?b2l(couch_doc:rev_to_str(NewTargetRev)) ++ "\""}],
> - update_doc_result_to_json(TargetDocId, {ok, NewTargetRev}));
> + update_doc(Req, Db, TargetDocId, Doc#doc{id=TargetDocId, revs=TargetRevs});
>
> db_doc_req(Req, _Db, _DocId) ->
> send_method_not_allowed(Req, "DELETE,GET,HEAD,POST,PUT,COPY").
> @@ -863,11 +802,17 @@ update_doc_result_to_json(DocId, Error) ->
> {[{id, DocId}, {error, ErrorStr}, {reason, Reason}]}.
>
>
> +update_doc(Req, Db, DocId, #doc{deleted=false}=Doc) ->
> + Loc = absolute_uri(Req, "/" ++ ?b2l(Db#db.name) ++ "/" ++ ?b2l(DocId)),
> + update_doc(Req, Db, DocId, Doc, [{"Location", Loc}]);
> update_doc(Req, Db, DocId, Doc) ->
> update_doc(Req, Db, DocId, Doc, []).
>
> update_doc(Req, Db, DocId, Doc, Headers) ->
> - update_doc(Req, Db, DocId, Doc, Headers, interactive_edit).
> + #doc_query_args{
> + update_type = UpdateType
> + } = parse_doc_query(Req),
> + update_doc(Req, Db, DocId, Doc, Headers, UpdateType).
>
> update_doc(Req, Db, DocId, #doc{deleted=Deleted}=Doc, Headers, UpdateType) ->
> case couch_httpd:header_value(Req, "X-Couch-Full-Commit") of
> @@ -878,14 +823,33 @@ update_doc(Req, Db, DocId, #doc{deleted=Deleted}=Doc, Headers, UpdateType) ->
> _ ->
> Options = []
> end,
> - {ok, NewRev} = couch_db:update_doc(Db, Doc, Options, UpdateType),
> - NewRevStr = couch_doc:rev_to_str(NewRev),
> - ResponseHeaders = [{"ETag", <<"\"", NewRevStr/binary, "\"">>}] ++ Headers,
> - send_json(Req, if Deleted -> 200; true -> 201 end,
> - ResponseHeaders, {[
> + case couch_httpd:qs_value(Req, "batch") of
> + "ok" ->
> + % async batching
> + spawn(fun() ->
> + case catch(couch_db:update_doc(Db, Doc, Options, UpdateType)) of
> + {ok, _} -> ok;
> + Error ->
> + ?LOG_INFO("Batch doc error (~s): ~p",[DocId, Error])
> + end
> + end),
> + send_json(Req, 202, Headers, {[
> {ok, true},
> - {id, DocId},
> - {rev, NewRevStr}]}).
> + {id, DocId}
> + ]});
> + _Normal ->
> + % normal
> + {ok, NewRev} = couch_db:update_doc(Db, Doc, Options, UpdateType),
> + NewRevStr = couch_doc:rev_to_str(NewRev),
> + ResponseHeaders = [{"ETag", <<"\"", NewRevStr/binary, "\"">>}] ++ Headers,
> + send_json(Req,
> + if Deleted orelse Req#httpd.method == 'DELETE' -> 200;
> + true -> 201 end,
> + ResponseHeaders, {[
> + {ok, true},
> + {id, DocId},
> + {rev, NewRevStr}]})
> + end.
>
> couch_doc_from_req(Req, DocId, #doc{revs=Revs}=Doc) ->
> validate_attachment_names(Doc),
> @@ -917,7 +881,6 @@ couch_doc_from_req(Req, DocId, #doc{revs=Revs}=Doc) ->
> couch_doc_from_req(Req, DocId, Json) ->
> couch_doc_from_req(Req, DocId, couch_doc:from_json_obj(Json)).
>
> -
> % Useful for debugging
> % couch_doc_open(Db, DocId) ->
> % couch_doc_open(Db, DocId, nil, []).
> @@ -1132,25 +1095,18 @@ db_attachment_req(#httpd{method=Method,mochi_req=MochiReq}=Req, Db, DocId, FileN
> DocEdited = Doc#doc{
> atts = NewAtt ++ [A || A <- Atts, A#att.name /= FileName]
> },
> - {ok, UpdatedRev} = couch_db:update_doc(Db, DocEdited, []),
> - #db{name=DbName} = Db,
>
> - {Status, Headers} = case Method of
> - 'DELETE' ->
> - {200, []};
> - _ ->
> - {201, [{"ETag", "\"" ++ ?b2l(couch_doc:rev_to_str(UpdatedRev)) ++ "\""},
> - {"Location", absolute_uri(Req, "/" ++
> - binary_to_list(DbName) ++ "/" ++
> - binary_to_list(DocId) ++ "/" ++
> - binary_to_list(FileName)
> - )}]}
> - end,
> - send_json(Req,Status, Headers, {[
> - {ok, true},
> - {id, DocId},
> - {rev, couch_doc:rev_to_str(UpdatedRev)}
> - ]});
> + Headers = case Method of
> + 'DELETE' ->
> + [];
> + _ ->
> + [{"Location", absolute_uri(Req, "/" ++
> + ?b2l(Db#db.name) ++ "/" ++
> + ?b2l(DocId) ++ "/" ++
> + ?b2l(FileName)
> + )}]
> + end,
> + update_doc(Req, Db, DocId, DocEdited, Headers);
>
> db_attachment_req(Req, _Db, _DocId, _FileNameParts) ->
> send_method_not_allowed(Req, "DELETE,GET,HEAD,PUT").
>
>
nice!