diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl index 0d435c2ffef..2304ba1fa56 100644 --- a/src/couch/src/couch_db.erl +++ b/src/couch/src/couch_db.erl @@ -77,6 +77,7 @@ get_full_doc_info/2, get_full_doc_infos/2, get_missing_revs/2, + get_design_doc/2, get_design_docs/1, get_design_doc_count/1, get_purge_infos/2, @@ -608,6 +609,19 @@ get_db_info(Db) -> ], {ok, InfoList}. +get_design_doc(#db{name = <<"shards/", _/binary>> = ShardDbName}, DDocId0) -> + DDocId = couch_util:normalize_ddoc_id(DDocId0), + DbName = mem3:dbname(ShardDbName), + {_, Ref} = spawn_monitor(fun() -> + exit(fabric:open_doc(DbName, DDocId, [])) + end), + receive {'DOWN', Ref, _, _, Response} -> + Response + end; +get_design_doc(#db{} = Db, DDocId0) -> + DDocId = couch_util:normalize_ddoc_id(DDocId0), + couch_db:open_doc_int(Db, DDocId, [ejson_body]). + get_design_docs(#db{name = <<"shards/", _/binary>> = ShardDbName}) -> DbName = mem3:dbname(ShardDbName), {_, Ref} = spawn_monitor(fun() -> exit(fabric:design_docs(DbName)) end), diff --git a/src/couch/src/couch_util.erl b/src/couch/src/couch_util.erl index 3efec84a9b2..ddd24aab000 100644 --- a/src/couch/src/couch_util.erl +++ b/src/couch/src/couch_util.erl @@ -27,6 +27,7 @@ -export([reorder_results/2]). -export([url_strip_password/1]). -export([encode_doc_id/1]). +-export([normalize_ddoc_id/1]). -export([with_db/2]). -export([rfc1123_date/0, rfc1123_date/1]). -export([integer_to_boolean/1, boolean_to_integer/1]). @@ -543,6 +544,10 @@ encode_doc_id(<<"_local/", Rest/binary>>) -> encode_doc_id(Id) -> url_encode(Id). +normalize_ddoc_id(<<"_design/", _/binary>> = DDocId) -> + DDocId; +normalize_ddoc_id(DDocId) when is_binary(DDocId) -> + <<"_design/", DDocId/binary>>. with_db(DbName, Fun) when is_binary(DbName) -> case couch_db:open_int(DbName, [?ADMIN_CTX]) of diff --git a/src/couch_mrview/src/couch_mrview_index.erl b/src/couch_mrview/src/couch_mrview_index.erl index 4718b562d2b..d3bcfe04bc6 100644 --- a/src/couch_mrview/src/couch_mrview_index.erl +++ b/src/couch_mrview/src/couch_mrview_index.erl @@ -226,16 +226,15 @@ verify_index_exists(DbName, Props) -> if Type =/= <<"mrview">> -> false; true -> DDocId = couch_util:get_value(<<"ddoc_id">>, Props), couch_util:with_db(DbName, fun(Db) -> - {ok, DesignDocs} = couch_db:get_design_docs(Db), - case get_ddoc(DbName, DesignDocs, DDocId) of - #doc{} = DDoc -> + case couch_db:get_design_doc(Db, DDocId) of + {ok, #doc{} = DDoc} -> {ok, IdxState} = couch_mrview_util:ddoc_to_mrst( DbName, DDoc), IdxSig = IdxState#mrst.sig, SigInLocal = couch_util:get_value( <<"signature">>, Props), couch_index_util:hexsig(IdxSig) == SigInLocal; - not_found -> + {not_found, _} -> false end end) @@ -245,25 +244,6 @@ verify_index_exists(DbName, Props) -> end. -get_ddoc(<<"shards/", _/binary>> = _DbName, DesignDocs, DDocId) -> - DDocs = [couch_doc:from_json_obj(DD) || DD <- DesignDocs], - case lists:keyfind(DDocId, #doc.id, DDocs) of - #doc{} = DDoc -> DDoc; - false -> not_found - end; -get_ddoc(DbName, DesignDocs, DDocId) -> - couch_util:with_db(DbName, fun(Db) -> - case lists:keyfind(DDocId, #full_doc_info.id, DesignDocs) of - #full_doc_info{} = DDocInfo -> - {ok, DDoc} = couch_db:open_doc_int( - Db, DDocInfo, [ejson_body]), - DDoc; - false -> - not_found - end - end). - - ensure_local_purge_docs(DbName, DDocs) -> couch_util:with_db(DbName, fun(Db) -> lists:foreach(fun(DDoc) ->