Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 93763 invoked from network); 9 Mar 2011 19:11:28 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 9 Mar 2011 19:11:28 -0000 Received: (qmail 67824 invoked by uid 500); 9 Mar 2011 19:11:28 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 67790 invoked by uid 500); 9 Mar 2011 19:11:28 -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 67783 invoked by uid 99); 9 Mar 2011 19:11:28 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 09 Mar 2011 19:11:28 +0000 X-ASF-Spam-Status: No, hits=-1998.9 required=5.0 tests=ALL_TRUSTED,FRT_OFFER2 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; Wed, 09 Mar 2011 19:11:27 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 0409123889C5; Wed, 9 Mar 2011 19:11:07 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1079943 - in /couchdb/branches/1.0.x: share/www/script/test/ src/couchdb/ Date: Wed, 09 Mar 2011 19:11:06 -0000 To: commits@couchdb.apache.org From: fdmanana@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110309191107.0409123889C5@eris.apache.org> Author: fdmanana Date: Wed Mar 9 19:11:06 2011 New Revision: 1079943 URL: http://svn.apache.org/viewvc?rev=1079943&view=rev Log: Merged revision 1079939 from trunk Parameter "include_docs" now honors parameter "conflicts" When querying a map view, /db/_all_docs/ or /db/_changes/ with "include_docs=true", if "conflicts=true" is given as well, the documents will contain the conflicts list (if there are conflicting revisions). Closes COUCHDB-549. Modified: couchdb/branches/1.0.x/share/www/script/test/all_docs.js couchdb/branches/1.0.x/share/www/script/test/view_include_docs.js couchdb/branches/1.0.x/src/couchdb/couch_changes.erl couchdb/branches/1.0.x/src/couchdb/couch_db.hrl couchdb/branches/1.0.x/src/couchdb/couch_httpd_db.erl couchdb/branches/1.0.x/src/couchdb/couch_httpd_show.erl couchdb/branches/1.0.x/src/couchdb/couch_httpd_view.erl Modified: couchdb/branches/1.0.x/share/www/script/test/all_docs.js URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/share/www/script/test/all_docs.js?rev=1079943&r1=1079942&r2=1079943&view=diff ============================================================================== --- couchdb/branches/1.0.x/share/www/script/test/all_docs.js (original) +++ couchdb/branches/1.0.x/share/www/script/test/all_docs.js Wed Mar 9 19:11:06 2011 @@ -105,20 +105,24 @@ couchTests.all_docs = function(debug) { var winRev = db.open("3"); - changes = db.changes({include_docs: true, style: "all_docs"}); + changes = db.changes({include_docs: true, conflicts: true, style: "all_docs"}); TEquals("3", changes.results[3].id); TEquals(3, changes.results[3].changes.length); TEquals(winRev._rev, changes.results[3].changes[0].rev); TEquals("3", changes.results[3].doc._id); TEquals(winRev._rev, changes.results[3].doc._rev); + TEquals(true, changes.results[3].doc._conflicts instanceof Array); + TEquals(2, changes.results[3].doc._conflicts.length); - rows = db.allDocs({include_docs: true}).rows; + rows = db.allDocs({include_docs: true, conflicts: true}).rows; TEquals(3, rows.length); TEquals("3", rows[2].key); TEquals("3", rows[2].id); TEquals(winRev._rev, rows[2].value.rev); TEquals(winRev._rev, rows[2].doc._rev); TEquals("3", rows[2].doc._id); + TEquals(true, rows[2].doc._conflicts instanceof Array); + TEquals(2, rows[2].doc._conflicts.length); // test the all docs collates sanely db.save({_id: "Z", foo: "Z"}); Modified: couchdb/branches/1.0.x/share/www/script/test/view_include_docs.js URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/share/www/script/test/view_include_docs.js?rev=1079943&r1=1079942&r2=1079943&view=diff ============================================================================== --- couchdb/branches/1.0.x/share/www/script/test/view_include_docs.js (original) +++ couchdb/branches/1.0.x/share/www/script/test/view_include_docs.js Wed Mar 9 19:11:06 2011 @@ -135,4 +135,58 @@ couchTests.view_include_docs = function( T(!resp.rows[0].doc); T(resp.rows[0].doc == null); T(resp.rows[1].doc.integer == 23); + + // COUCHDB-549 - include_docs=true with conflicts=true + + var dbA = new CouchDB("test_suite_db_a", {"X-Couch-Full-Commit":"false"}); + var dbB = new CouchDB("test_suite_db_b", {"X-Couch-Full-Commit":"false"}); + + dbA.deleteDb(); + dbA.createDb(); + dbB.deleteDb(); + dbB.createDb(); + + var ddoc = { + _id: "_design/mydesign", + language : "javascript", + views : { + myview : { + map: (function(doc) { + emit(doc.value, 1); + }).toString() + } + } + }; + TEquals(true, dbA.save(ddoc).ok); + + var doc1a = {_id: "foo", value: 1, str: "1"}; + TEquals(true, dbA.save(doc1a).ok); + + var doc1b = {_id: "foo", value: 1, str: "666"}; + TEquals(true, dbB.save(doc1b).ok); + + var doc2 = {_id: "bar", value: 2, str: "2"}; + TEquals(true, dbA.save(doc2).ok); + + TEquals(true, CouchDB.replicate(dbA.name, dbB.name).ok); + + doc1b = dbB.open("foo", {conflicts: true}); + TEquals(true, doc1b._conflicts instanceof Array); + TEquals(1, doc1b._conflicts.length); + var conflictRev = doc1b._conflicts[0]; + + doc2 = dbB.open("bar", {conflicts: true}); + TEquals("undefined", typeof doc2._conflicts); + + resp = dbB.view("mydesign/myview", {include_docs: true, conflicts: true}); + + TEquals(2, resp.rows.length); + TEquals(true, resp.rows[0].doc._conflicts instanceof Array); + TEquals(1, resp.rows[0].doc._conflicts.length); + TEquals(conflictRev, resp.rows[0].doc._conflicts[0]); + TEquals("undefined", typeof resp.rows[1].doc._conflicts); + + // cleanup + dbA.deleteDb(); + dbB.deleteDb(); }; Modified: couchdb/branches/1.0.x/src/couchdb/couch_changes.erl URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/src/couchdb/couch_changes.erl?rev=1079943&r1=1079942&r2=1079943&view=diff ============================================================================== --- couchdb/branches/1.0.x/src/couchdb/couch_changes.erl (original) +++ couchdb/branches/1.0.x/src/couchdb/couch_changes.erl Wed Mar 9 19:11:06 2011 @@ -56,7 +56,7 @@ handle_changes(#changes_args{style=Style true -> fun(Callback) -> start_sending_changes(Callback, Args#changes_args.feed), - {ok, {_, LastSeq, _Prepend, _, _, _, _, _}} = + {ok, {_, LastSeq, _Prepend, _, _, _, _, _, _}} = send_changes( Args#changes_args{feed="normal"}, Callback, @@ -146,6 +146,7 @@ send_changes(Args, Callback, Db, StartSe #changes_args{ style = Style, include_docs = IncludeDocs, + conflicts = Conflicts, limit = Limit, feed = ResponseType, dir = Dir, @@ -158,7 +159,7 @@ send_changes(Args, Callback, Db, StartSe fun changes_enumerator/2, [{dir, Dir}], {Db, StartSeq, Prepend, FilterFun, Callback, ResponseType, Limit, - IncludeDocs} + IncludeDocs, Conflicts} ). keep_sending_changes(Args, Callback, Db, StartSeq, Prepend, Timeout, @@ -168,7 +169,7 @@ keep_sending_changes(Args, Callback, Db, limit = Limit } = Args, % ?LOG_INFO("send_changes start ~p",[StartSeq]), - {ok, {_, EndSeq, Prepend2, _, _, _, NewLimit, _}} = send_changes( + {ok, {_, EndSeq, Prepend2, _, _, _, NewLimit, _, _}} = send_changes( Args#changes_args{dir=fwd}, Callback, Db, StartSeq, Prepend ), % ?LOG_INFO("send_changes last ~p",[EndSeq]), @@ -203,7 +204,7 @@ end_sending_changes(Callback, EndSeq, Re Callback({stop, EndSeq}, ResponseType). changes_enumerator(DocInfo, {Db, _, _, FilterFun, Callback, "continuous", - Limit, IncludeDocs}) -> + Limit, IncludeDocs, Conflicts}) -> #doc_info{high_seq = Seq} = DocInfo, Results0 = FilterFun(DocInfo), @@ -212,17 +213,17 @@ changes_enumerator(DocInfo, {Db, _, _, F case Results of [] -> {Go, {Db, Seq, nil, FilterFun, Callback, "continuous", Limit, - IncludeDocs} + IncludeDocs, Conflicts} }; _ -> - ChangesRow = changes_row(Db, Results, DocInfo, IncludeDocs), + ChangesRow = changes_row(Db, Results, DocInfo, IncludeDocs, Conflicts), Callback({change, ChangesRow, <<"">>}, "continuous"), {Go, {Db, Seq, nil, FilterFun, Callback, "continuous", Limit - 1, - IncludeDocs} + IncludeDocs, Conflicts} } end; changes_enumerator(DocInfo, {Db, _, Prepend, FilterFun, Callback, ResponseType, - Limit, IncludeDocs}) -> + Limit, IncludeDocs, Conflicts}) -> #doc_info{high_seq = Seq} = DocInfo, Results0 = FilterFun(DocInfo), @@ -231,25 +232,28 @@ changes_enumerator(DocInfo, {Db, _, Prep case Results of [] -> {Go, {Db, Seq, Prepend, FilterFun, Callback, ResponseType, Limit, - IncludeDocs} + IncludeDocs, Conflicts} }; _ -> - ChangesRow = changes_row(Db, Results, DocInfo, IncludeDocs), + ChangesRow = changes_row(Db, Results, DocInfo, IncludeDocs, Conflicts), Callback({change, ChangesRow, Prepend}, ResponseType), {Go, {Db, Seq, <<",\n">>, FilterFun, Callback, ResponseType, Limit - 1, - IncludeDocs} + IncludeDocs, Conflicts} } end. -changes_row(Db, Results, DocInfo, IncludeDoc) -> +changes_row(Db, Results, DocInfo, IncludeDoc, Conflicts) -> #doc_info{ id = Id, high_seq = Seq, revs = [#rev_info{deleted = Del} | _] } = DocInfo, {[{<<"seq">>, Seq}, {<<"id">>, Id}, {<<"changes">>, Results}] ++ deleted_item(Del) ++ case IncludeDoc of - true -> couch_httpd_view:doc_member(Db, DocInfo); - false -> [] + true -> + Options = if Conflicts -> [conflicts]; true -> [] end, + couch_httpd_view:doc_member(Db, DocInfo, Options); + false -> + [] end}. deleted_item(true) -> [{deleted, true}]; Modified: couchdb/branches/1.0.x/src/couchdb/couch_db.hrl URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/src/couchdb/couch_db.hrl?rev=1079943&r1=1079942&r2=1079943&view=diff ============================================================================== --- couchdb/branches/1.0.x/src/couchdb/couch_db.hrl (original) +++ couchdb/branches/1.0.x/src/couchdb/couch_db.hrl Wed Mar 9 19:11:06 2011 @@ -193,6 +193,7 @@ view_type = nil, include_docs = false, + conflicts = false, stale = false, multi_get = false, callback = nil, @@ -283,6 +284,7 @@ heartbeat, timeout, filter = "", - include_docs = false + include_docs = false, + conflicts = false }). Modified: couchdb/branches/1.0.x/src/couchdb/couch_httpd_db.erl URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/src/couchdb/couch_httpd_db.erl?rev=1079943&r1=1079942&r2=1079943&view=diff ============================================================================== --- couchdb/branches/1.0.x/src/couchdb/couch_httpd_db.erl (original) +++ couchdb/branches/1.0.x/src/couchdb/couch_httpd_db.erl Wed Mar 9 19:11:06 2011 @@ -498,7 +498,7 @@ all_docs_view(Req, Db, Keys) -> FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs, CurrentEtag, Db, UpdateSeq, TotalRowCount, #view_fold_helper_funs{ reduce_count = fun couch_db:enum_docs_reduce_to_count/1, - send_row = fun all_docs_send_json_view_row/5 + send_row = fun all_docs_send_json_view_row/6 }), AdapterFun = fun(#full_doc_info{id=Id}=FullDocInfo, Offset, Acc) -> case couch_doc:to_doc_info(FullDocInfo) of @@ -516,7 +516,7 @@ all_docs_view(Req, Db, Keys) -> FoldlFun = couch_httpd_view:make_view_fold_fun(Req, QueryArgs, CurrentEtag, Db, UpdateSeq, TotalRowCount, #view_fold_helper_funs{ reduce_count = fun(Offset) -> Offset end, - send_row = fun all_docs_send_json_view_row/5 + send_row = fun all_docs_send_json_view_row/6 }), KeyFoldFun = case Dir of fwd -> @@ -543,21 +543,22 @@ all_docs_view(Req, Db, Keys) -> end end). -all_docs_send_json_view_row(Resp, Db, KV, IncludeDocs, RowFront) -> - JsonRow = all_docs_view_row_obj(Db, KV, IncludeDocs), +all_docs_send_json_view_row(Resp, Db, KV, IncludeDocs, Conflicts, RowFront) -> + JsonRow = all_docs_view_row_obj(Db, KV, IncludeDocs, Conflicts), send_chunk(Resp, RowFront ++ ?JSON_ENCODE(JsonRow)), {ok, ",\r\n"}. -all_docs_view_row_obj(_Db, {{DocId, error}, Value}, _IncludeDocs) -> +all_docs_view_row_obj(_Db, {{DocId, error}, Value}, _IncludeDocs, _Conflicts) -> {[{key, DocId}, {error, Value}]}; -all_docs_view_row_obj(Db, {_KeyDocId, DocInfo}, true) -> +all_docs_view_row_obj(Db, {_KeyDocId, DocInfo}, true, Conflicts) -> case DocInfo of #doc_info{revs = [#rev_info{deleted = true} | _]} -> {all_docs_row(DocInfo) ++ [{doc, null}]}; _ -> - {all_docs_row(DocInfo) ++ couch_httpd_view:doc_member(Db, DocInfo)} + {all_docs_row(DocInfo) ++ couch_httpd_view:doc_member( + Db, DocInfo, if Conflicts -> [conflicts]; true -> [] end)} end; -all_docs_view_row_obj(_Db, {_KeyDocId, DocInfo}, _IncludeDocs) -> +all_docs_view_row_obj(_Db, {_KeyDocId, DocInfo}, _IncludeDocs, _Conflicts) -> {all_docs_row(DocInfo)}. all_docs_row(#doc_info{id = Id, revs = [RevInfo | _]}) -> @@ -1163,6 +1164,8 @@ parse_changes_query(Req) -> Args#changes_args{timeout=list_to_integer(Value)}; {"include_docs", "true"} -> Args#changes_args{include_docs=true}; + {"conflicts", "true"} -> + Args#changes_args{conflicts=true}; {"filter", _} -> Args#changes_args{filter=Value}; _Else -> % unknown key value pair, ignore. Modified: couchdb/branches/1.0.x/src/couchdb/couch_httpd_show.erl URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/src/couchdb/couch_httpd_show.erl?rev=1079943&r1=1079942&r2=1079943&view=diff ============================================================================== --- couchdb/branches/1.0.x/src/couchdb/couch_httpd_show.erl (original) +++ couchdb/branches/1.0.x/src/couchdb/couch_httpd_show.erl Wed Mar 9 19:11:06 2011 @@ -307,18 +307,20 @@ start_list_resp(QServer, LName, Req, Db, {ok, Resp, ?b2l(?l2b(Chunks))}. make_map_send_row_fun(QueryServer) -> - fun(Resp, Db, Row, IncludeDocs, RowFront) -> - send_list_row(Resp, QueryServer, Db, Row, RowFront, IncludeDocs) + fun(Resp, Db, Row, IncludeDocs, Conflicts, RowFront) -> + send_list_row( + Resp, QueryServer, Db, Row, RowFront, IncludeDocs, Conflicts) end. make_reduce_send_row_fun(QueryServer, Db) -> fun(Resp, Row, RowFront) -> - send_list_row(Resp, QueryServer, Db, Row, RowFront, false) + send_list_row(Resp, QueryServer, Db, Row, RowFront, false, false) end. -send_list_row(Resp, QueryServer, Db, Row, RowFront, IncludeDoc) -> +send_list_row(Resp, QueryServer, Db, Row, RowFront, IncludeDoc, Conflicts) -> try - [Go,Chunks] = prompt_list_row(QueryServer, Db, Row, IncludeDoc), + [Go,Chunks] = prompt_list_row( + QueryServer, Db, Row, IncludeDoc, Conflicts), Chunk = RowFront ++ ?b2l(?l2b(Chunks)), send_non_empty_chunk(Resp, Chunk), case Go of @@ -334,11 +336,12 @@ send_list_row(Resp, QueryServer, Db, Row end. -prompt_list_row({Proc, _DDocId}, Db, {{Key, DocId}, Value}, IncludeDoc) -> - JsonRow = couch_httpd_view:view_row_obj(Db, {{Key, DocId}, Value}, IncludeDoc), +prompt_list_row({Proc, _DDocId}, Db, {{_Key, _DocId}, _} = Kv, + IncludeDoc, Conflicts) -> + JsonRow = couch_httpd_view:view_row_obj(Db, Kv, IncludeDoc, Conflicts), couch_query_servers:proc_prompt(Proc, [<<"list_row">>, JsonRow]); -prompt_list_row({Proc, _DDocId}, _, {Key, Value}, _IncludeDoc) -> +prompt_list_row({Proc, _DDocId}, _, {Key, Value}, _IncludeDoc, _Conflicts) -> JsonRow = {[{key, Key}, {value, Value}]}, couch_query_servers:proc_prompt(Proc, [<<"list_row">>, JsonRow]). Modified: couchdb/branches/1.0.x/src/couchdb/couch_httpd_view.erl URL: http://svn.apache.org/viewvc/couchdb/branches/1.0.x/src/couchdb/couch_httpd_view.erl?rev=1079943&r1=1079942&r2=1079943&view=diff ============================================================================== --- couchdb/branches/1.0.x/src/couchdb/couch_httpd_view.erl (original) +++ couchdb/branches/1.0.x/src/couchdb/couch_httpd_view.erl Wed Mar 9 19:11:06 2011 @@ -16,9 +16,9 @@ -export([handle_view_req/3,handle_temp_view_req/2]). -export([get_stale_type/1, get_reduce_type/1, parse_view_params/3]). --export([make_view_fold_fun/7, finish_view_fold/4, finish_view_fold/5, view_row_obj/3]). +-export([make_view_fold_fun/7, finish_view_fold/4, finish_view_fold/5, view_row_obj/4]). -export([view_group_etag/2, view_group_etag/3, make_reduce_fold_funs/6]). --export([design_doc_view/5, parse_bool_param/1, doc_member/2]). +-export([design_doc_view/5, parse_bool_param/1, doc_member/3]). -export([make_key_options/1, load_view/4]). -import(couch_httpd, @@ -303,6 +303,8 @@ parse_view_param("reduce", Value) -> [{reduce, parse_bool_param(Value)}]; parse_view_param("include_docs", Value) -> [{include_docs, parse_bool_param(Value)}]; +parse_view_param("conflicts", Value) -> + [{conflicts, parse_bool_param(Value)}]; parse_view_param("list", Value) -> [{list, ?l2b(Value)}]; parse_view_param("callback", _) -> @@ -387,6 +389,15 @@ validate_view_query(include_docs, true, % Use the view_query_args record's default value validate_view_query(include_docs, _Value, Args) -> Args; +validate_view_query(conflicts, true, Args) -> + case Args#view_query_args.view_type of + reduce -> + Msg = <<"Query parameter `conflicts` " + "is invalid for reduce views.">>, + throw({query_parse_error, Msg}); + _ -> + Args#view_query_args{conflicts = true} + end; validate_view_query(extra, _Value, Args) -> Args. @@ -398,7 +409,8 @@ make_view_fold_fun(Req, QueryArgs, Etag, } = apply_default_helper_funs(HelperFuns), #view_query_args{ - include_docs = IncludeDocs + include_docs = IncludeDocs, + conflicts = Conflicts } = QueryArgs, fun({{Key, DocId}, Value}, OffsetReds, @@ -416,12 +428,12 @@ make_view_fold_fun(Req, QueryArgs, Etag, {ok, Resp2, RowFunAcc0} = StartRespFun(Req, Etag, TotalViewCount, Offset, RowFunAcc, UpdateSeq), {Go, RowFunAcc2} = SendRowFun(Resp2, Db, {{Key, DocId}, Value}, - IncludeDocs, RowFunAcc0), + IncludeDocs, Conflicts, RowFunAcc0), {Go, {AccLimit - 1, 0, Resp2, RowFunAcc2}}; {AccLimit, _, Resp} when (AccLimit > 0) -> % rendering all other rows {Go, RowFunAcc2} = SendRowFun(Resp, Db, {{Key, DocId}, Value}, - IncludeDocs, RowFunAcc), + IncludeDocs, Conflicts, RowFunAcc), {Go, {AccLimit - 1, 0, Resp, RowFunAcc2}} end end. @@ -497,7 +509,7 @@ apply_default_helper_funs( end, SendRow2 = case SendRow of - undefined -> fun send_json_view_row/5; + undefined -> fun send_json_view_row/6; _ -> SendRow end, @@ -570,8 +582,8 @@ json_view_start_resp(Req, Etag, TotalVie end, {ok, Resp, BeginBody}. -send_json_view_row(Resp, Db, {{Key, DocId}, Value}, IncludeDocs, RowFront) -> - JsonObj = view_row_obj(Db, {{Key, DocId}, Value}, IncludeDocs), +send_json_view_row(Resp, Db, Kv, IncludeDocs, Conflicts, RowFront) -> + JsonObj = view_row_obj(Db, Kv, IncludeDocs, Conflicts), send_chunk(Resp, RowFront ++ ?JSON_ENCODE(JsonObj)), {ok, ",\r\n"}. @@ -600,10 +612,10 @@ view_group_etag(#group{sig=Sig,current_s couch_httpd:make_etag({Sig, CurrentSeq, Extra}). % the view row has an error -view_row_obj(_Db, {{Key, error}, Value}, _IncludeDocs) -> +view_row_obj(_Db, {{Key, error}, Value}, _IncludeDocs, _Conflicts) -> {[{key, Key}, {error, Value}]}; % include docs in the view output -view_row_obj(Db, {{Key, DocId}, {Props}}, true) -> +view_row_obj(Db, {{Key, DocId}, {Props}}, true, Conflicts) -> Rev = case couch_util:get_value(<<"_rev">>, Props) of undefined -> nil; @@ -611,27 +623,29 @@ view_row_obj(Db, {{Key, DocId}, {Props}} couch_doc:parse_rev(Rev0) end, IncludeId = couch_util:get_value(<<"_id">>, Props, DocId), - view_row_with_doc(Db, {{Key, DocId}, {Props}}, {IncludeId, Rev}); -view_row_obj(Db, {{Key, DocId}, Value}, true) -> - view_row_with_doc(Db, {{Key, DocId}, Value}, {DocId, nil}); + view_row_with_doc(Db, {{Key, DocId}, {Props}}, {IncludeId, Rev}, Conflicts); +view_row_obj(Db, {{Key, DocId}, Value}, true, Conflicts) -> + view_row_with_doc(Db, {{Key, DocId}, Value}, {DocId, nil}, Conflicts); % the normal case for rendering a view row -view_row_obj(_Db, {{Key, DocId}, Value}, _IncludeDocs) -> +view_row_obj(_Db, {{Key, DocId}, Value}, _IncludeDocs, _Conflicts) -> {[{id, DocId}, {key, Key}, {value, Value}]}. -view_row_with_doc(Db, {{Key, DocId}, Value}, IdRev) -> - {[{id, DocId}, {key, Key}, {value, Value}] ++ doc_member(Db, IdRev)}. +view_row_with_doc(Db, {{Key, DocId}, Value}, IdRev, Conflicts) -> + {[{id, DocId}, {key, Key}, {value, Value}] ++ + doc_member(Db, IdRev, if Conflicts -> [conflicts]; true -> [] end)}. -doc_member(Db, #doc_info{id = Id, revs = [#rev_info{rev = Rev} | _]} = Info) -> +doc_member(Db, #doc_info{id = Id, revs = [#rev_info{rev = Rev} | _]} = Info, + Options) -> ?LOG_DEBUG("Include Doc: ~p ~p", [Id, Rev]), - case couch_db:open_doc(Db, Info, [deleted]) of + case couch_db:open_doc(Db, Info, [deleted | Options]) of {ok, Doc} -> [{doc, couch_doc:to_json_obj(Doc, [])}]; _ -> [{doc, null}] end; -doc_member(Db, {DocId, Rev}) -> +doc_member(Db, {DocId, Rev}, Options) -> ?LOG_DEBUG("Include Doc: ~p ~p", [DocId, Rev]), - case (catch couch_httpd_db:couch_doc_open(Db, DocId, Rev, [])) of + case (catch couch_httpd_db:couch_doc_open(Db, DocId, Rev, Options)) of #doc{} = Doc -> JsonDoc = couch_doc:to_json_obj(Doc, []), [{doc, JsonDoc}];