Skip to content
This repository has been archived by the owner on Oct 22, 2021. It is now read-only.

Commit

Permalink
Merge remote branch 'apache/1.1.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
kocolosk committed Oct 4, 2011
2 parents 33b60ba + e779492 commit 4e19639
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 19 deletions.
1 change: 1 addition & 0 deletions apps/couch/THANKS
Expand Up @@ -82,5 +82,6 @@ suggesting improvements or submitting changes. Some of these people are:
* Caolan McMahon <caolan.mcmahon@googlemail.com> * Caolan McMahon <caolan.mcmahon@googlemail.com>
* Alexander Shorin <kxepal@gmail.com> * Alexander Shorin <kxepal@gmail.com>
* Christopher Bonhage <queezey@me.com> * Christopher Bonhage <queezey@me.com>
* Christian Carter <cdcarter@gmail.com>


For a list of authors see the `AUTHORS` file. For a list of authors see the `AUTHORS` file.
16 changes: 7 additions & 9 deletions apps/couch/src/couch_httpd_show.erl
Expand Up @@ -127,7 +127,7 @@ handle_doc_update_req(Req, _Db, _DDoc) ->
send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) -> send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) ->
JsonReq = couch_httpd_external:json_req_obj(Req, Db, DocId), JsonReq = couch_httpd_external:json_req_obj(Req, Db, DocId),
JsonDoc = couch_query_servers:json_doc(Doc), JsonDoc = couch_query_servers:json_doc(Doc),
{Code, JsonResp1} = case couch_query_servers:ddoc_prompt(DDoc, JsonResp1 = case couch_query_servers:ddoc_prompt(DDoc,
[<<"updates">>, UpdateName], [JsonDoc, JsonReq]) of [<<"updates">>, UpdateName], [JsonDoc, JsonReq]) of
[<<"up">>, {NewJsonDoc}, {JsonResp}] -> [<<"up">>, {NewJsonDoc}, {JsonResp}] ->
Options = case couch_httpd:header_value(Req, "X-Couch-Full-Commit", Options = case couch_httpd:header_value(Req, "X-Couch-Full-Commit",
Expand All @@ -140,16 +140,14 @@ send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) ->
NewDoc = couch_doc:from_json_obj({NewJsonDoc}), NewDoc = couch_doc:from_json_obj({NewJsonDoc}),
{ok, NewRev} = couch_db:update_doc(Db, NewDoc, Options), {ok, NewRev} = couch_db:update_doc(Db, NewDoc, Options),
NewRevStr = couch_doc:rev_to_str(NewRev), NewRevStr = couch_doc:rev_to_str(NewRev),
JsonRespWithRev = {[{<<"headers">>, {[{<<"code">>, 201}, {<<"headers">>,
{[{<<"X-Couch-Update-NewRev">>, NewRevStr}]}} | JsonResp]}, {[{<<"X-Couch-Update-NewRev">>, NewRevStr}]}} | JsonResp]};
{201, JsonRespWithRev}; [<<"up">>, _Other, {JsonResp}] ->
[<<"up">>, _Other, JsonResp] -> {[{<<"code">>, 200} | JsonResp]}
{200, JsonResp}
end, end,


JsonResp2 = couch_util:json_apply_field({<<"code">>, Code}, JsonResp1),
% todo set location field % todo set location field
couch_httpd_external:send_external_response(Req, JsonResp2). couch_httpd_external:send_external_response(Req, JsonResp1).




% view-list request with view and list from same design doc. % view-list request with view and list from same design doc.
Expand Down
25 changes: 21 additions & 4 deletions apps/couch/src/couch_rep_changes_feed.erl
Expand Up @@ -491,13 +491,30 @@ purge_req_messages(ReqId) ->
ok ok
end. end.


queue_changes_row(Row, #state{doc_ids = nil, count = Count, rows = Rows}) -> queue_changes_row(Row, #state{doc_ids = nil} = State) ->
{queue:in(Row, Rows), Count + 1}; maybe_queue_row(Row, State);
queue_changes_row({RowProps} = Row, queue_changes_row({RowProps} = Row,
#state{doc_ids = Ids, count = Count, rows = Rows}) -> #state{doc_ids = Ids, count = Count, rows = Rows} = State) ->
case lists:member(get_value(<<"id">>, RowProps), Ids) of case lists:member(get_value(<<"id">>, RowProps), Ids) of
true -> true ->
{queue:in(Row, Rows), Count + 1}; maybe_queue_row(Row, State);
false -> false ->
{Rows, Count} {Rows, Count}
end. end.

maybe_queue_row({Props} = Row, #state{count = Count, rows = Rows} = State) ->
case get_value(<<"id">>, Props) of
<<>> ->
[_, Db | _] = State#state.init_args,
?LOG_ERROR("Replicator: ignoring document with empty ID in source "
"database `~s` (_changes sequence ~p)",
[dbname(Db), couch_util:get_value(<<"seq">>, Props)]),
{Rows, Count};
_ ->
{queue:in(Row, Rows), Count + 1}
end.

dbname(#http_db{url = Url}) ->
couch_util:url_strip_password(Url);
dbname(#db{name = Name}) ->
Name.
28 changes: 28 additions & 0 deletions apps/couch/src/test_util.erl
Expand Up @@ -14,6 +14,7 @@


-export([init_code_path/0]). -export([init_code_path/0]).
-export([source_file/1, build_file/1, config_files/0]). -export([source_file/1, build_file/1, config_files/0]).
-export([request/3, request/4]).


init_code_path() -> init_code_path() ->
code:load_abs("apps/couch/test/etap/etap"). code:load_abs("apps/couch/test/etap/etap").
Expand All @@ -31,3 +32,30 @@ config_files() ->
source_file("test/etap/random_port.ini") source_file("test/etap/random_port.ini")
]. ].


request(Url, Headers, Method) ->
request(Url, Headers, Method, []).

request(Url, Headers, Method, Body) ->
request(Url, Headers, Method, Body, 3).

request(_Url, _Headers, _Method, _Body, 0) ->
{error, request_failed};
request(Url, Headers, Method, Body, N) ->
case code:is_loaded(ibrowse) of
false ->
{ok, _} = ibrowse:start();
_ ->
ok
end,
case ibrowse:send_req(Url, Headers, Method, Body) of
{ok, Code0, RespHeaders, RespBody0} ->
Code = list_to_integer(Code0),
RespBody = iolist_to_binary(RespBody0),
{ok, Code, RespHeaders, RespBody};
{error, {'EXIT', {normal, _}}} ->
% Connection closed right after a successful request that
% used the same connection.
request(Url, Headers, Method, Body, N - 1);
Error ->
Error
end.
24 changes: 24 additions & 0 deletions rel/overlay/share/www/script/test/update_documents.js
Expand Up @@ -75,6 +75,17 @@ couchTests.update_documents = function(debug) {
}), }),
"get-uuid" : stringFun(function(doc, req) { "get-uuid" : stringFun(function(doc, req) {
return [null, req.uuid]; return [null, req.uuid];
}),
"code-n-bump" : stringFun(function(doc,req) {
if (!doc.counter) doc.counter = 0;
doc.counter += 1;
var message = "<h1>bumped it!</h1>";
resp = {"code": 302, "body": message}
return [doc, resp];
}),
"resp-code" : stringFun(function(doc,req) {
resp = {"code": 302}
return [null, resp];
}) })
} }
}; };
Expand Down Expand Up @@ -179,4 +190,17 @@ couchTests.update_documents = function(debug) {


var doc = db.open("with/slash"); var doc = db.open("with/slash");
TEquals(2, doc.counter, "counter should be 2"); TEquals(2, doc.counter, "counter should be 2");

// COUCHDB-648 - the code in the JSON response should be honored

xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/code-n-bump/"+docid, {
headers : {"X-Couch-Full-Commit":"true"}
});
T(xhr.status == 302);
T(xhr.responseText == "<h1>bumped it!</h1>");
doc = db.open(docid);
T(doc.counter == 3);

xhr = CouchDB.request("POST", "/test_suite_db/_design/update/_update/resp-code/");
T(xhr.status == 302);
}; };
8 changes: 2 additions & 6 deletions test/etap/072-cleanup.t
Expand Up @@ -41,7 +41,6 @@ main(_) ->
test() -> test() ->


{ok, _} = couch_server_sup:start_link(test_util:config_files()), {ok, _} = couch_server_sup:start_link(test_util:config_files()),
ok = application:start(inets),
couch_server:delete(?TEST_DB, []), couch_server:delete(?TEST_DB, []),
timer:sleep(1000), timer:sleep(1000),


Expand Down Expand Up @@ -110,11 +109,8 @@ db_url() ->
binary_to_list(?TEST_DB). binary_to_list(?TEST_DB).


query_view(DDoc, View) -> query_view(DDoc, View) ->
{ok, {{_, Code, _}, _Headers, _Body}} = http:request( {ok, Code, _Headers, _Body} = test_util:request(
get, db_url() ++ "/_design/" ++ DDoc ++ "/_view/" ++ View, [], get),
{db_url() ++ "/_design/" ++ DDoc ++ "/_view/" ++ View, []},
[],
[{sync, true}]),
etap:is(Code, 200, "Built view index for " ++ DDoc ++ "."), etap:is(Code, 200, "Built view index for " ++ DDoc ++ "."),
ok. ok.


Expand Down

0 comments on commit 4e19639

Please sign in to comment.