You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by be...@apache.org on 2014/02/15 10:49:55 UTC

[49/59] [abbrv] remove couch_mrview

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/src/couch_mrview_updater.erl
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/src/couch_mrview_updater.erl b/apps/couch_mrview/src/couch_mrview_updater.erl
deleted file mode 100644
index be1055c..0000000
--- a/apps/couch_mrview/src/couch_mrview_updater.erl
+++ /dev/null
@@ -1,424 +0,0 @@
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
--module(couch_mrview_updater).
-
--export([start_update/3, purge/4, process_doc/3, finish_update/1]).
-
--include_lib("couch/include/couch_db.hrl").
--include_lib("couch_mrview/include/couch_mrview.hrl").
-
-
-start_update(Partial, State, NumChanges) ->
-    QueueOpts = [{max_size, 100000}, {max_items, 500}],
-    {ok, DocQueue} = couch_work_queue:new(QueueOpts),
-    {ok, WriteQueue} = couch_work_queue:new(QueueOpts),
-
-    InitState = State#mrst{
-        first_build=State#mrst.update_seq==0,
-        partial_resp_pid=Partial,
-        doc_acc=[],
-        doc_queue=DocQueue,
-        write_queue=WriteQueue
-    },
-
-    Self = self(),
-    MapFun = fun() ->
-        couch_task_status:add_task([
-            {type, indexer},
-            {database, State#mrst.db_name},
-            {design_document, State#mrst.idx_name},
-            {progress, 0},
-            {changes_done, 0},
-            {total_changes, NumChanges}
-        ]),
-        couch_task_status:set_update_frequency(500),
-        map_docs(Self, InitState)
-    end,
-    WriteFun = fun() -> write_results(Self, InitState) end,
-
-    spawn_link(MapFun),
-    spawn_link(WriteFun),
-
-    {ok, InitState}.
-
-
-purge(_Db, PurgeSeq, PurgedIdRevs, State) ->
-    #mrst{
-        id_btree=IdBtree,
-        log_btree=LogBtree,
-        views=Views
-    } = State,
-
-    Ids = [Id || {Id, _Revs} <- PurgedIdRevs],
-    {ok, Lookups, LLookups, LogBtree2, IdBtree2} = case LogBtree of
-        nil ->
-            {ok, L, Bt} = couch_btree:query_modify(IdBtree, Ids, [], Ids),
-            {ok, L, [], nil, Bt};
-        _ ->
-            {ok, L, Bt} = couch_btree:query_modify(IdBtree, Ids, [], Ids),
-            {ok, LL, LBt} = couch_btree:query_modify(LogBtree, Ids, [], Ids),
-            {ok, L, LL, LBt, Bt}
-    end,
-
-    MakeDictFun = fun
-        ({ok, {DocId, ViewNumRowKeys}}, DictAcc) ->
-            FoldFun = fun
-                ({ViewNum, {Key, Seq, _Op}}, DictAcc2) ->
-                    dict:append(ViewNum, {Key, Seq, DocId}, DictAcc2);
-                ({ViewNum, RowKey}, DictAcc2) ->
-                    dict:append(ViewNum, {RowKey, DocId}, DictAcc2)
-            end,
-            lists:foldl(FoldFun, DictAcc, ViewNumRowKeys);
-        ({not_found, _}, DictAcc) ->
-            DictAcc
-    end,
-    KeysToRemove = lists:foldl(MakeDictFun, dict:new(), Lookups),
-    SeqsToRemove = lists:foldl(MakeDictFun, dict:new(), LLookups),
-
-    RemKeysFun = fun(#mrview{id_num=ViewId}=View) ->
-        ToRem = couch_util:dict_find(ViewId, KeysToRemove, []),
-        {ok, VBtree2} = couch_btree:add_remove(View#mrview.btree, [], ToRem),
-        NewPurgeSeq = case VBtree2 =/= View#mrview.btree of
-            true -> PurgeSeq;
-            _ -> View#mrview.purge_seq
-        end,
-        {SeqBtree2, KeyBySeqBtree2} = case View#mrview.seq_indexed of
-            true ->
-                SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []),
-                SKs = [{Seq, Key} || {Key, Seq, _} <- SToRem],
-                KSs = [{[Seq, Key], DocId} || {Key, Seq, DocId} <- SToRem],
-                {ok, SBt} = couch_btree:add_remove(View#mrview.seq_btree,
-                                                   [], SKs),
-                {ok, KSbt} = couch_btree:add_remove(View#mrview.key_byseq_btree,
-                                                    [], KSs),
-                {SBt, KSbt};
-            _ -> {nil, nil}
-        end,
-        View#mrview{btree=VBtree2,
-                    seq_btree=SeqBtree2,
-                    key_byseq_btree=KeyBySeqBtree2,
-                    purge_seq=NewPurgeSeq}
-
-    end,
-
-    Views2 = lists:map(RemKeysFun, Views),
-    {ok, State#mrst{
-        id_btree=IdBtree2,
-        log_btree=LogBtree2,
-        views=Views2,
-        purge_seq=PurgeSeq
-    }}.
-
-
-process_doc(Doc, Seq, #mrst{doc_acc=Acc}=State) when length(Acc) > 100 ->
-    couch_work_queue:queue(State#mrst.doc_queue, lists:reverse(Acc)),
-    process_doc(Doc, Seq, State#mrst{doc_acc=[]});
-process_doc(nil, Seq, #mrst{doc_acc=Acc}=State) ->
-    {ok, State#mrst{doc_acc=[{nil, Seq, nil} | Acc]}};
-process_doc(#doc{id=Id, deleted=true}, Seq, #mrst{doc_acc=Acc}=State) ->
-    {ok, State#mrst{doc_acc=[{Id, Seq, deleted} | Acc]}};
-process_doc(#doc{id=Id}=Doc, Seq, #mrst{doc_acc=Acc}=State) ->
-    {ok, State#mrst{doc_acc=[{Id, Seq, Doc} | Acc]}}.
-
-
-finish_update(#mrst{doc_acc=Acc}=State) ->
-    if Acc /= [] ->
-        couch_work_queue:queue(State#mrst.doc_queue, Acc);
-        true -> ok
-    end,
-    couch_work_queue:close(State#mrst.doc_queue),
-    receive
-        {new_state, NewState} ->
-            {ok, NewState#mrst{
-                first_build=undefined,
-                partial_resp_pid=undefined,
-                doc_acc=undefined,
-                doc_queue=undefined,
-                write_queue=undefined,
-                qserver=nil
-            }}
-    end.
-
-
-map_docs(Parent, State0) ->
-    case couch_work_queue:dequeue(State0#mrst.doc_queue) of
-        closed ->
-            couch_query_servers:stop_doc_map(State0#mrst.qserver),
-            couch_work_queue:close(State0#mrst.write_queue);
-        {ok, Dequeued} ->
-            % Run all the non deleted docs through the view engine and
-            % then pass the results on to the writer process.
-            State1 = case State0#mrst.qserver of
-                nil -> start_query_server(State0);
-                _ -> State0
-            end,
-            QServer = State1#mrst.qserver,
-            DocFun = fun
-                ({nil, Seq, _}, {SeqAcc, Results}) ->
-                    {erlang:max(Seq, SeqAcc), Results};
-                ({Id, Seq, deleted}, {SeqAcc, Results}) ->
-                    {erlang:max(Seq, SeqAcc), [{Id, Seq, []} | Results]};
-                ({Id, Seq, Doc}, {SeqAcc, Results}) ->
-                    {ok, Res} = couch_query_servers:map_doc_raw(QServer, Doc),
-                    {erlang:max(Seq, SeqAcc), [{Id, Seq, Res} | Results]}
-            end,
-            FoldFun = fun(Docs, Acc) ->
-                update_task(length(Docs)),
-                lists:foldl(DocFun, Acc, Docs)
-            end,
-            Results = lists:foldl(FoldFun, {0, []}, Dequeued),
-            couch_work_queue:queue(State1#mrst.write_queue, Results),
-            map_docs(Parent, State1)
-    end.
-
-
-write_results(Parent, State) ->
-    case couch_work_queue:dequeue(State#mrst.write_queue) of
-        closed ->
-            Parent ! {new_state, State};
-        {ok, Info} ->
-            EmptyKVs = [{V#mrview.id_num, {[], []}} || V <- State#mrst.views],
-            {Seq, ViewKVs, DocIdKeys, Log} = merge_results(Info, 0, EmptyKVs,
-                                                           [], dict:new()),
-            NewState = write_kvs(State, Seq, ViewKVs, DocIdKeys, Log),
-            send_partial(NewState#mrst.partial_resp_pid, NewState),
-            write_results(Parent, NewState)
-    end.
-
-
-start_query_server(State) ->
-    #mrst{
-        language=Language,
-        lib=Lib,
-        views=Views
-    } = State,
-    Defs = [View#mrview.def || View <- Views],
-    {ok, QServer} = couch_query_servers:start_doc_map(Language, Defs, Lib),
-    State#mrst{qserver=QServer}.
-
-
-merge_results([], SeqAcc, ViewKVs, DocIdKeys, Log) ->
-    {SeqAcc, ViewKVs, DocIdKeys, Log};
-merge_results([{Seq, Results} | Rest], SeqAcc, ViewKVs, DocIdKeys, Log) ->
-    Fun = fun(RawResults, {VKV, DIK, Log2}) ->
-        merge_results(RawResults, VKV, DIK, Log2)
-    end,
-    {ViewKVs1, DocIdKeys1, Log1} = lists:foldl(Fun, {ViewKVs, DocIdKeys, Log},
-                                               Results),
-    merge_results(Rest, erlang:max(Seq, SeqAcc), ViewKVs1, DocIdKeys1,
-                  Log1).
-
-
-merge_results({DocId, _Seq, []}, ViewKVs, DocIdKeys, Log) ->
-    {ViewKVs, [{DocId, []} | DocIdKeys], dict:store(DocId, [], Log)};
-merge_results({DocId, Seq, RawResults}, ViewKVs, DocIdKeys, Log) ->
-    JsonResults = couch_query_servers:raw_to_ejson(RawResults),
-    Results = [[list_to_tuple(Res) || Res <- FunRs] || FunRs <- JsonResults],
-    {ViewKVs1, ViewIdKeys, Log1} = insert_results(DocId, Seq, Results, ViewKVs, [],
-                                            [], Log),
-    {ViewKVs1, [ViewIdKeys | DocIdKeys], Log1}.
-
-
-insert_results(DocId, _Seq, [], [], ViewKVs, ViewIdKeys, Log) ->
-    {lists:reverse(ViewKVs), {DocId, ViewIdKeys}, Log};
-insert_results(DocId, Seq, [KVs | RKVs], [{Id, {VKVs, SKVs}} | RVKVs], VKVAcc,
-               VIdKeys, Log) ->
-    CombineDupesFun = fun
-        ({Key, Val}, {[{Key, {dups, Vals}} | Rest], IdKeys, Log2}) ->
-            {[{Key, {dups, [Val | Vals]}} | Rest], IdKeys, Log2};
-        ({Key, Val1}, {[{Key, Val2} | Rest], IdKeys, Log2}) ->
-            {[{Key, {dups, [Val1, Val2]}} | Rest], IdKeys, Log2};
-        ({Key, _}=KV, {Rest, IdKeys, Log2}) ->
-            {[KV | Rest], [{Id, Key} | IdKeys],
-             dict:append(DocId, {Id, {Key, Seq, add}}, Log2)}
-    end,
-    InitAcc = {[], VIdKeys, Log},
-    {Duped, VIdKeys0, Log1} = lists:foldl(CombineDupesFun, InitAcc,
-                                          lists:sort(KVs)),
-    FinalKVs = [{{Key, DocId}, Val} || {Key, Val} <- Duped] ++ VKVs,
-    FinalSKVs = [{{Seq, Key}, {DocId, Val}} || {Key, Val} <- Duped] ++ SKVs,
-    insert_results(DocId, Seq, RKVs, RVKVs,
-                  [{Id, {FinalKVs, FinalSKVs}} | VKVAcc], VIdKeys0, Log1).
-
-
-write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys, Log) ->
-    #mrst{
-        id_btree=IdBtree,
-        log_btree=LogBtree,
-        first_build=FirstBuild
-    } = State,
-
-    {ok, ToRemove, IdBtree2} = update_id_btree(IdBtree, DocIdKeys, FirstBuild),
-    ToRemByView = collapse_rem_keys(ToRemove, dict:new()),
-
-    {ok, SeqsToAdd, SeqsToRemove, LogBtree2} = case LogBtree of
-        nil -> {ok, undefined, undefined, nil};
-        _ -> update_log(LogBtree, Log, UpdateSeq, FirstBuild)
-    end,
-
-    UpdateView = fun(#mrview{id_num=ViewId}=View, {ViewId, {KVs, SKVs}}) ->
-        ToRem = couch_util:dict_find(ViewId, ToRemByView, []),
-        {ok, VBtree2} = couch_btree:add_remove(View#mrview.btree, KVs, ToRem),
-        NewUpdateSeq = case VBtree2 =/= View#mrview.btree of
-            true -> UpdateSeq;
-            _ -> View#mrview.update_seq
-        end,
-
-        %% store the view changes.
-        {SeqBtree2, KeyBySeqBtree2} = case View#mrview.seq_indexed of
-            true ->
-                SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []),
-                SToAdd = couch_util:dict_find(ViewId, SeqsToAdd, []),
-                RemSKs = [{Seq, Key} || {Key, Seq, _} <- SToRem],
-                RemKSs = [{[Key, Seq], DocId} || {Key, Seq, DocId} <- SToRem],
-                SKVs1 = SKVs ++ SToAdd,
-                {ok, SBt} = couch_btree:add_remove(View#mrview.seq_btree,
-                                                   SKVs1, RemSKs),
-
-                {ok, KSbt} = couch_btree:add_remove(View#mrview.key_byseq_btree,
-                                                    couch_mrview_util:to_key_seq(SKVs1),
-                                                    RemKSs),
-                {SBt, KSbt};
-            _ -> {nil, nil}
-        end,
-        View#mrview{btree=VBtree2,
-                    seq_btree=SeqBtree2,
-                    key_byseq_btree=KeyBySeqBtree2,
-                    update_seq=NewUpdateSeq}
-    end,
-
-    State#mrst{
-        views=lists:zipwith(UpdateView, State#mrst.views, ViewKVs),
-        update_seq=UpdateSeq,
-        id_btree=IdBtree2,
-        log_btree=LogBtree2
-    }.
-
-
-update_id_btree(Btree, DocIdKeys, true) ->
-    ToAdd = [{Id, DIKeys} || {Id, DIKeys} <- DocIdKeys, DIKeys /= []],
-    couch_btree:query_modify(Btree, [], ToAdd, []);
-update_id_btree(Btree, DocIdKeys, _) ->
-    ToFind = [Id || {Id, _} <- DocIdKeys],
-    ToAdd = [{Id, DIKeys} || {Id, DIKeys} <- DocIdKeys, DIKeys /= []],
-    ToRem = [Id || {Id, DIKeys} <- DocIdKeys, DIKeys == []],
-    couch_btree:query_modify(Btree, ToFind, ToAdd, ToRem).
-
-walk_log(BTree, Fun, Acc, Ids) ->
-    WrapFun = fun(KV, _Offset, Acc2) ->
-            Fun(KV, Acc2)
-    end,
-    lists:foldl(fun(Id, Acc1) ->
-                Opt = [{start_key, Id}, {end_key, Id}],
-                {ok, _, A} = couch_btree:fold(BTree, WrapFun, Acc1, Opt),
-                A
-        end, Acc, Ids).
-
-update_log(Btree, Log, _UpdatedSeq, true) ->
-    ToAdd = [{Id, DIKeys} || {Id, DIKeys} <- dict:to_list(Log),
-                             DIKeys /= []],
-    {ok, LogBtree2} = couch_btree:add_remove(Btree, ToAdd, []),
-    {ok, dict:new(), dict:new(), LogBtree2};
-update_log(Btree, Log, UpdatedSeq, _) ->
-    %% build list of updated keys and Id
-    {ToLook, Updated} = dict:fold(fun
-                (Id, [], {IdsAcc, KeysAcc}) ->
-                    {[Id | IdsAcc], KeysAcc};
-                (Id, DIKeys, {IdsAcc, KeysAcc}) ->
-                    KeysAcc1 = lists:foldl(fun({ViewId, {Key, _Seq, _Op}},
-                                               KeysAcc2) ->
-                                    [{Id, ViewId, Key} | KeysAcc2]
-                            end, KeysAcc, DIKeys),
-                {[Id | IdsAcc], KeysAcc1} end, {[], []}, Log),
-
-    RemValue = {[{<<"_removed">>, true}]},
-    {Log1, AddAcc, DelAcc} = walk_log(Btree, fun({DocId, VIdKeys},
-                                                          {Log2, AddAcc2, DelAcc2}) ->
-
-                {Log3, AddAcc3, DelAcc3} = lists:foldl(fun({ViewId,{Key, Seq, Op}},
-                                                           {Log4, AddAcc4, DelAcc4}) ->
-
-                            case lists:member({DocId, ViewId, Key}, Updated) of
-                                true ->
-                                    %% the log is updated, deleted old
-                                    %% record from the view
-                                    DelAcc5 = dict:append(ViewId,
-                                                          {Key, Seq, DocId},
-                                                          DelAcc4),
-                                    {Log4, AddAcc4, DelAcc5};
-                                false when Op /= del ->
-                                    %% an update operation has been
-                                    %% logged for this key. We must now
-                                    %% record it as deleted in the
-                                    %% log, remove the old record in
-                                    %% the view and update the view
-                                    %% with a removed record.
-                                    Log5 = dict:append(DocId,
-                                                       {ViewId,
-                                                        {Key,UpdatedSeq, del}},
-                                                       Log4),
-                                    DelAcc5 = dict:append(ViewId,
-                                                          {Key, Seq, DocId},
-                                                          DelAcc4),
-                                    AddAcc5 = dict:append(ViewId,
-                                                          {{UpdatedSeq, Key},
-                                                           {DocId, RemValue}},
-                                                          AddAcc4),
-                                    {Log5, AddAcc5, DelAcc5};
-                                false ->
-                                    %% the key has already been
-                                    %% registered in the view as
-                                    %% deleted, make sure to add it
-                                    %% to the new log.
-                                    Log5 = dict:append(DocId,
-                                                       {ViewId,
-                                                        {Key, Seq, del}}, Log4),
-                                    {Log5, AddAcc4, DelAcc4}
-                            end
-                    end, {Log2, AddAcc2, DelAcc2}, VIdKeys),
-                    {ok, {Log3, AddAcc3, DelAcc3}}
-            end, {Log, dict:new(), dict:new()}, ToLook),
-
-    ToAdd = [{Id, DIKeys} || {Id, DIKeys} <- dict:to_list(Log1), DIKeys /= []],
-    %% store the new logs
-    {ok, LogBtree2} = couch_btree:add_remove(Btree, ToAdd, []),
-    {ok, AddAcc, DelAcc, LogBtree2}.
-
-collapse_rem_keys([], Acc) ->
-    Acc;
-collapse_rem_keys([{ok, {DocId, ViewIdKeys}} | Rest], Acc) ->
-    NewAcc = lists:foldl(fun({ViewId, Key}, Acc2) ->
-        dict:append(ViewId, {Key, DocId}, Acc2)
-    end, Acc, ViewIdKeys),
-    collapse_rem_keys(Rest, NewAcc);
-collapse_rem_keys([{not_found, _} | Rest], Acc) ->
-    collapse_rem_keys(Rest, Acc).
-
-
-send_partial(Pid, State) when is_pid(Pid) ->
-    gen_server:cast(Pid, {new_state, State});
-send_partial(_, _) ->
-    ok.
-
-
-update_task(NumChanges) ->
-    [Changes, Total] = couch_task_status:get([changes_done, total_changes]),
-    Changes2 = Changes + NumChanges,
-    Progress = case Total of
-        0 ->
-            % updater restart after compaction finishes
-            0;
-        _ ->
-            (Changes2 * 100) div Total
-    end,
-    couch_task_status:update([{progress, Progress}, {changes_done, Changes2}]).

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/src/couch_mrview_util.erl
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/src/couch_mrview_util.erl b/apps/couch_mrview/src/couch_mrview_util.erl
deleted file mode 100644
index a98f042..0000000
--- a/apps/couch_mrview/src/couch_mrview_util.erl
+++ /dev/null
@@ -1,950 +0,0 @@
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
--module(couch_mrview_util).
-
--export([get_view/4]).
--export([ddoc_to_mrst/2, init_state/4, reset_index/3]).
--export([make_header/1]).
--export([index_file/2, compaction_file/2, open_file/1]).
--export([delete_files/2, delete_index_file/2, delete_compaction_file/2]).
--export([get_row_count/1, all_docs_reduce_to_count/1, reduce_to_count/1]).
--export([get_view_changes_count/1]).
--export([all_docs_key_opts/1, all_docs_key_opts/2, key_opts/1, key_opts/2]).
--export([fold/4, fold_reduce/4]).
--export([temp_view_to_ddoc/1]).
--export([calculate_data_size/3]).
--export([validate_args/1]).
--export([maybe_load_doc/3, maybe_load_doc/4]).
--export([maybe_update_index_file/1]).
--export([changes_key_opts/2]).
--export([fold_changes/4]).
--export([to_key_seq/1]).
-
--define(MOD, couch_mrview_index).
-
--include_lib("couch/include/couch_db.hrl").
--include_lib("couch_mrview/include/couch_mrview.hrl").
-
-
-get_view(Db, DDoc, ViewName, Args0) ->
-    ArgCheck = fun(InitState) ->
-        Args1 = set_view_type(Args0, ViewName, InitState#mrst.views),
-        {ok, validate_args(Args1)}
-    end,
-    {ok, Pid, Args2} = couch_index_server:get_index(?MOD, Db, DDoc, ArgCheck),
-    DbUpdateSeq = couch_util:with_db(Db, fun(WDb) ->
-        couch_db:get_update_seq(WDb)
-    end),
-    MinSeq = case Args2#mrargs.stale of
-        ok -> 0; update_after -> 0; _ -> DbUpdateSeq
-    end,
-    {ok, State} = case couch_index:get_state(Pid, MinSeq) of
-        {ok, _} = Resp -> Resp;
-        Error -> throw(Error)
-    end,
-    couch_ref_counter:add(State#mrst.refc),
-    if Args2#mrargs.stale == update_after ->
-        spawn(fun() -> catch couch_index:get_state(Pid, DbUpdateSeq) end);
-        true -> ok
-    end,
-    #mrst{language=Lang, views=Views} = State,
-    {Type, View, Args3} = extract_view(Lang, Args2, ViewName, Views),
-    check_range(Args3, view_cmp(View)),
-    Sig = view_sig(Db, State, View, Args3),
-    {ok, {Type, View}, Sig, Args3}.
-
-
-ddoc_to_mrst(DbName, #doc{id=Id, body={Fields}}) ->
-    MakeDict = fun({Name, {MRFuns}}, DictBySrcAcc) ->
-        case couch_util:get_value(<<"map">>, MRFuns) of
-            MapSrc when is_binary(MapSrc) ->
-                RedSrc = couch_util:get_value(<<"reduce">>, MRFuns, null),
-                {ViewOpts} = couch_util:get_value(<<"options">>, MRFuns, {[]}),
-                View = case dict:find({MapSrc, ViewOpts}, DictBySrcAcc) of
-                    {ok, View0} -> View0;
-                    error -> #mrview{def=MapSrc, options=ViewOpts}
-                end,
-                {MapNames, RedSrcs} = case RedSrc of
-                    null ->
-                        MNames = [Name | View#mrview.map_names],
-                        {MNames, View#mrview.reduce_funs};
-                    _ ->
-                        RedFuns = [{Name, RedSrc} | View#mrview.reduce_funs],
-                        {View#mrview.map_names, RedFuns}
-                end,
-                View2 = View#mrview{map_names=MapNames, reduce_funs=RedSrcs},
-                dict:store({MapSrc, ViewOpts}, View2, DictBySrcAcc);
-            undefined ->
-                DictBySrcAcc
-        end
-    end,
-    {DesignOpts} = proplists:get_value(<<"options">>, Fields, {[]}),
-    SeqIndexed = proplists:get_value(<<"seq_indexed">>, DesignOpts, false),
-
-    {RawViews} = couch_util:get_value(<<"views">>, Fields, {[]}),
-    BySrc = lists:foldl(MakeDict, dict:new(), RawViews),
-
-    NumViews = fun({_, View}, N) ->
-            {View#mrview{id_num=N, seq_indexed=SeqIndexed}, N+1}
-    end,
-    {Views, _} = lists:mapfoldl(NumViews, 0, lists:sort(dict:to_list(BySrc))),
-
-    Language = couch_util:get_value(<<"language">>, Fields, <<"javascript">>),
-    Lib = couch_util:get_value(<<"lib">>, RawViews, {[]}),
-
-    IdxState = #mrst{
-        db_name=DbName,
-        idx_name=Id,
-        lib=Lib,
-        views=Views,
-        language=Language,
-        design_opts=DesignOpts,
-        seq_indexed=SeqIndexed
-    },
-    SigInfo = {Views, Language, DesignOpts, couch_index_util:sort_lib(Lib)},
-    {ok, IdxState#mrst{sig=couch_util:md5(term_to_binary(SigInfo))}}.
-
-
-set_view_type(_Args, _ViewName, []) ->
-    throw({not_found, missing_named_view});
-set_view_type(Args, ViewName, [View | Rest]) ->
-    RedNames = [N || {N, _} <- View#mrview.reduce_funs],
-    case lists:member(ViewName, RedNames) of
-        true ->
-            case Args#mrargs.reduce of
-                false -> Args#mrargs{view_type=map};
-                _ -> Args#mrargs{view_type=red}
-            end;
-        false ->
-            case lists:member(ViewName, View#mrview.map_names) of
-                true -> Args#mrargs{view_type=map};
-                false -> set_view_type(Args, ViewName, Rest)
-            end
-    end.
-
-
-extract_view(_Lang, _Args, _ViewName, []) ->
-    throw({not_found, missing_named_view});
-extract_view(Lang, #mrargs{view_type=map}=Args, Name, [View | Rest]) ->
-    Names = View#mrview.map_names ++ [N || {N, _} <- View#mrview.reduce_funs],
-    case lists:member(Name, Names) of
-        true -> {map, View, Args};
-        _ -> extract_view(Lang, Args, Name, Rest)
-    end;
-extract_view(Lang, #mrargs{view_type=red}=Args, Name, [View | Rest]) ->
-    RedNames = [N || {N, _} <- View#mrview.reduce_funs],
-    case lists:member(Name, RedNames) of
-        true -> {red, {index_of(Name, RedNames), Lang, View}, Args};
-        false -> extract_view(Lang, Args, Name, Rest)
-    end.
-
-
-view_sig(Db, State, View, #mrargs{include_docs=true}=Args) ->
-    BaseSig = view_sig(Db, State, View, Args#mrargs{include_docs=false}),
-    UpdateSeq = couch_db:get_update_seq(Db),
-    PurgeSeq = couch_db:get_purge_seq(Db),
-    Bin = term_to_binary({BaseSig, UpdateSeq, PurgeSeq,
-                          State#mrst.seq_indexed}),
-    couch_index_util:hexsig(couch_util:md5(Bin));
-view_sig(Db, State, {_Nth, _Lang, View}, Args) ->
-    view_sig(Db, State, View, Args);
-view_sig(_Db, State, View, Args0) ->
-    Sig = State#mrst.sig,
-    UpdateSeq = View#mrview.update_seq,
-    PurgeSeq = View#mrview.purge_seq,
-    SeqIndexed = View#mrview.seq_indexed,
-    Args = Args0#mrargs{
-        preflight_fun=undefined,
-        extra=[]
-    },
-    Bin = term_to_binary({Sig, UpdateSeq, PurgeSeq, SeqIndexed, Args}),
-    couch_index_util:hexsig(couch_util:md5(Bin)).
-
-
-init_state(Db, Fd, #mrst{views=Views}=State, nil) ->
-    Header = #mrheader{
-        seq=0,
-        purge_seq=couch_db:get_purge_seq(Db),
-        id_btree_state=nil,
-        log_btree_state=nil,
-        view_states=[{nil, nil, nil, 0, 0} || _ <- Views]
-    },
-    init_state(Db, Fd, State, Header);
-% read <= 1.2.x header record and transpile it to >=1.3.x
-% header record
-init_state(Db, Fd, State, #index_header{
-    seq=Seq,
-    purge_seq=PurgeSeq,
-    id_btree_state=IdBtreeState,
-    view_states=ViewStates}) ->
-    init_state(Db, Fd, State, #mrheader{
-        seq=Seq,
-        purge_seq=PurgeSeq,
-        id_btree_state=IdBtreeState,
-        log_btree_state=nil,
-        view_states=[{Bt, nil, nil, USeq, PSeq} || {Bt, USeq, PSeq} <- ViewStates]
-        });
-init_state(Db, Fd, State, Header) ->
-    #mrst{language=Lang, views=Views, seq_indexed=SeqIndexed} = State,
-    #mrheader{
-        seq=Seq,
-        purge_seq=PurgeSeq,
-        id_btree_state=IdBtreeState,
-        log_btree_state=LogBtreeState,
-        view_states=ViewStates
-    } = Header,
-
-    StateUpdate = fun
-        ({_, _, _, _, _}=St) -> St;
-        (St) -> {St, nil, nil, 0, 0}
-    end,
-    ViewStates2 = lists:map(StateUpdate, ViewStates),
-
-    IdBtOpts = [{compression, couch_db:compression(Db)}],
-    {ok, IdBtree} = couch_btree:open(IdBtreeState, Fd, IdBtOpts),
-    {ok, LogBtree} = case SeqIndexed of
-        true -> couch_btree:open(LogBtreeState, Fd, IdBtOpts);
-        false -> {ok, nil}
-    end,
-
-    OpenViewFun = fun(St, View) -> open_view(Db, Fd, Lang, St, View) end,
-    Views2 = lists:zipwith(OpenViewFun, ViewStates2, Views),
-
-    State#mrst{
-        fd=Fd,
-        update_seq=Seq,
-        purge_seq=PurgeSeq,
-        id_btree=IdBtree,
-        log_btree=LogBtree,
-        views=Views2
-    }.
-
-less_json_seqs({SeqA, _JsonA}, {SeqB, _JsonB}) ->
-    couch_ejson_compare:less(SeqA, SeqB) < 0.
-
-open_view(Db, Fd, Lang, {BTState, SeqBTState, KSeqBTState, USeq, PSeq}, View) ->
-    FunSrcs = [FunSrc || {_Name, FunSrc} <- View#mrview.reduce_funs],
-    ReduceFun =
-        fun(reduce, KVs) ->
-            KVs2 = detuple_kvs(expand_dups(KVs, []), []),
-            {ok, Result} = couch_query_servers:reduce(Lang, FunSrcs, KVs2),
-            {length(KVs2), Result};
-        (rereduce, Reds) ->
-            Count = lists:sum([Count0 || {Count0, _} <- Reds]),
-            UsrReds = [UsrRedsList || {_, UsrRedsList} <- Reds],
-            {ok, Result} = couch_query_servers:rereduce(Lang, FunSrcs, UsrReds),
-            {Count, Result}
-        end,
-
-    Less = case couch_util:get_value(<<"collation">>, View#mrview.options) of
-        <<"raw">> -> fun(A, B) -> A < B end;
-        _ -> fun couch_ejson_compare:less_json_ids/2
-    end,
-
-    ViewBtOpts = [
-        {less, Less},
-        {reduce, ReduceFun},
-        {compression, couch_db:compression(Db)}
-    ],
-    {ok, Btree} = couch_btree:open(BTState, Fd, ViewBtOpts),
-
-    {SeqBtree, KeyBySeqBtree} = case View#mrview.seq_indexed of
-        true ->
-            BySeqReduceFun = fun couch_db_updater:btree_by_seq_reduce/2,
-            ViewSeqBtOpts = [{less, fun less_json_seqs/2},
-                             {reduce, BySeqReduceFun},
-                             {compression, couch_db:compression(Db)}],
-            KeyBySeqBtOpts = [{less, Less},
-                              {reduce, BySeqReduceFun},
-                              {compression, couch_db:compression(Db)}],
-            {ok, SBt} = couch_btree:open(SeqBTState, Fd, ViewSeqBtOpts),
-            {ok, KSBt} = couch_btree:open(KSeqBTState, Fd, KeyBySeqBtOpts),
-            {SBt, KSBt};
-        false ->
-            {nil, nil}
-    end,
-
-    View#mrview{btree=Btree,
-                seq_btree=SeqBtree,
-                key_byseq_btree=KeyBySeqBtree,
-                update_seq=USeq,
-                purge_seq=PSeq}.
-
-
-temp_view_to_ddoc({Props}) ->
-    Language = couch_util:get_value(<<"language">>, Props, <<"javascript">>),
-    Options = couch_util:get_value(<<"options">>, Props, {[]}),
-    View0 = [{<<"map">>, couch_util:get_value(<<"map">>, Props)}],
-    View1 = View0 ++ case couch_util:get_value(<<"reduce">>, Props) of
-        RedSrc when is_binary(RedSrc) -> [{<<"reduce">>, RedSrc}];
-        _ -> []
-    end,
-    DDoc = {[
-        {<<"_id">>, couch_uuids:random()},
-        {<<"language">>, Language},
-        {<<"options">>, Options},
-        {<<"views">>, {[
-            {<<"temp">>, {View1}}
-        ]}}
-    ]},
-    couch_doc:from_json_obj(DDoc).
-
-
-get_row_count(#mrview{btree=Bt}) ->
-    {ok, {Count, _Reds}} = couch_btree:full_reduce(Bt),
-    {ok, Count}.
-
-
-all_docs_reduce_to_count(Reductions) ->
-    Reduce = fun couch_db_updater:btree_by_id_reduce/2,
-    {Count, _, _} = couch_btree:final_reduce(Reduce, Reductions),
-    Count.
-
-reduce_to_count(nil) ->
-    0;
-reduce_to_count(Reductions) ->
-    Reduce = fun
-        (reduce, KVs) ->
-            Counts = [
-                case V of {dups, Vals} -> length(Vals); _ -> 1 end
-                || {_,V} <- KVs
-            ],
-            {lists:sum(Counts), []};
-        (rereduce, Reds) ->
-            {lists:sum([Count0 || {Count0, _} <- Reds]), []}
-    end,
-    {Count, _} = couch_btree:final_reduce(Reduce, Reductions),
-    Count.
-
-%% @doc get all changes for a view
-get_view_changes_count(#mrview{seq_btree=Btree}) ->
-    couch_btree:fold_reduce(
-            Btree, fun(_SeqStart, PartialReds, 0) ->
-                    {ok, couch_btree:final_reduce(Btree, PartialReds)}
-            end,0, []).
-
-fold(#mrview{btree=Bt}, Fun, Acc, Opts) ->
-    WrapperFun = fun(KV, Reds, Acc2) ->
-        fold_fun(Fun, expand_dups([KV], []), Reds, Acc2)
-    end,
-    {ok, _LastRed, _Acc} = couch_btree:fold(Bt, WrapperFun, Acc, Opts).
-
-fold_fun(_Fun, [], _, Acc) ->
-    {ok, Acc};
-fold_fun(Fun, [KV|Rest], {KVReds, Reds}, Acc) ->
-    case Fun(KV, {KVReds, Reds}, Acc) of
-        {ok, Acc2} ->
-            fold_fun(Fun, Rest, {[KV|KVReds], Reds}, Acc2);
-        {stop, Acc2} ->
-            {stop, Acc2}
-    end.
-
-
-fold_changes(Bt, Fun, Acc, Opts) ->
-    WrapperFun = fun(KV, _Reds, Acc2) ->
-        fold_changes_fun(Fun, changes_expand_dups([KV], []), Acc2)
-    end,
-    {ok, _LastRed, _Acc} = couch_btree:fold(Bt, WrapperFun, Acc, Opts).
-
-fold_changes_fun(_Fun, [], Acc) ->
-    {ok, Acc};
-fold_changes_fun(Fun, [KV|Rest],  Acc) ->
-    case Fun(KV, Acc) of
-        {ok, Acc2} ->
-            fold_changes_fun(Fun, Rest, Acc2);
-        {stop, Acc2} ->
-            {stop, Acc2}
-    end.
-
-
-fold_reduce({NthRed, Lang, View}, Fun,  Acc, Options) ->
-    #mrview{
-        btree=Bt,
-        reduce_funs=RedFuns
-    } = View,
-    LPad = lists:duplicate(NthRed - 1, []),
-    RPad = lists:duplicate(length(RedFuns) - NthRed, []),
-    {_Name, FunSrc} = lists:nth(NthRed,RedFuns),
-
-    ReduceFun = fun
-        (reduce, KVs0) ->
-            KVs1 = detuple_kvs(expand_dups(KVs0, []), []),
-            {ok, Red} = couch_query_servers:reduce(Lang, [FunSrc], KVs1),
-            {0, LPad ++ Red ++ RPad};
-        (rereduce, Reds) ->
-            ExtractRed = fun({_, UReds0}) -> [lists:nth(NthRed, UReds0)] end,
-            UReds = lists:map(ExtractRed, Reds),
-            {ok, Red} = couch_query_servers:rereduce(Lang, [FunSrc], UReds),
-            {0, LPad ++ Red ++ RPad}
-    end,
-
-    WrapperFun = fun({GroupedKey, _}, PartialReds, Acc0) ->
-        {_, Reds} = couch_btree:final_reduce(ReduceFun, PartialReds),
-        Fun(GroupedKey, lists:nth(NthRed, Reds), Acc0)
-    end,
-
-    couch_btree:fold_reduce(Bt, WrapperFun, Acc, Options).
-
-
-validate_args(Args) ->
-    Reduce = Args#mrargs.reduce,
-    case Reduce == undefined orelse is_boolean(Reduce) of
-        true -> ok;
-        _ -> mrverror(<<"Invalid `reduce` value.">>)
-    end,
-
-    case {Args#mrargs.view_type, Reduce} of
-        {map, true} -> mrverror(<<"Reduce is invalid for map-only views.">>);
-        _ -> ok
-    end,
-
-    case {Args#mrargs.view_type, Args#mrargs.group_level, Args#mrargs.keys} of
-        {red, exact, _} -> ok;
-        {red, _, KeyList} when is_list(KeyList) ->
-            Msg = <<"Multi-key fetchs for reduce views must use `group=true`">>,
-            mrverror(Msg);
-        _ -> ok
-    end,
-
-    case Args#mrargs.keys of
-        Keys when is_list(Keys) -> ok;
-        undefined -> ok;
-        _ -> mrverror(<<"`keys` must be an array of strings.">>)
-    end,
-
-    case {Args#mrargs.keys, Args#mrargs.start_key} of
-        {undefined, _} -> ok;
-        {[], _} -> ok;
-        {[_|_], undefined} -> ok;
-        _ -> mrverror(<<"`start_key` is incompatible with `keys`">>)
-    end,
-
-    case Args#mrargs.start_key_docid of
-        undefined -> ok;
-        SKDocId0 when is_binary(SKDocId0) -> ok;
-        _ -> mrverror(<<"`start_key_docid` must be a string.">>)
-    end,
-
-    case {Args#mrargs.keys, Args#mrargs.end_key} of
-        {undefined, _} -> ok;
-        {[], _} -> ok;
-        {[_|_], undefined} -> ok;
-        _ -> mrverror(<<"`end_key` is incompatible with `keys`">>)
-    end,
-
-    case Args#mrargs.end_key_docid of
-        undefined -> ok;
-        EKDocId0 when is_binary(EKDocId0) -> ok;
-        _ -> mrverror(<<"`end_key_docid` must be a string.">>)
-    end,
-
-    case Args#mrargs.direction of
-        fwd -> ok;
-        rev -> ok;
-        _ -> mrverror(<<"Invalid direction.">>)
-    end,
-
-    case {Args#mrargs.limit >= 0, Args#mrargs.limit == undefined} of
-        {true, _} -> ok;
-        {_, true} -> ok;
-        _ -> mrverror(<<"`limit` must be a positive integer.">>)
-    end,
-
-    case Args#mrargs.skip < 0 of
-        true -> mrverror(<<"`skip` must be >= 0">>);
-        _ -> ok
-    end,
-
-    case {Args#mrargs.view_type, Args#mrargs.group_level} of
-        {red, exact} -> ok;
-        {_, 0} -> ok;
-        {red, Int} when is_integer(Int), Int >= 0 -> ok;
-        {red, _} -> mrverror(<<"`group_level` must be >= 0">>);
-        {map, _} -> mrverror(<<"Invalid use of grouping on a map view.">>)
-    end,
-
-    case Args#mrargs.stale of
-        ok -> ok;
-        update_after -> ok;
-        false -> ok;
-        _ -> mrverror(<<"Invalid value for `stale`.">>)
-    end,
-
-    case is_boolean(Args#mrargs.inclusive_end) of
-        true -> ok;
-        _ -> mrverror(<<"Invalid value for `inclusive_end`.">>)
-    end,
-
-    case {Args#mrargs.view_type, Args#mrargs.include_docs} of
-        {red, true} -> mrverror(<<"`include_docs` is invalid for reduce">>);
-        {_, ID} when is_boolean(ID) -> ok;
-        _ -> mrverror(<<"Invalid value for `include_docs`">>)
-    end,
-
-    case {Args#mrargs.view_type, Args#mrargs.conflicts} of
-        {_, undefined} -> ok;
-        {map, V} when is_boolean(V) -> ok;
-        {red, undefined} -> ok;
-        {map, _} -> mrverror(<<"Invalid value for `conflicts`.">>);
-        {red, _} -> mrverror(<<"`conflicts` is invalid for reduce views.">>)
-    end,
-
-    SKDocId = case {Args#mrargs.direction, Args#mrargs.start_key_docid} of
-        {fwd, undefined} -> <<>>;
-        {rev, undefined} -> <<255>>;
-        {_, SKDocId1} -> SKDocId1
-    end,
-
-    EKDocId = case {Args#mrargs.direction, Args#mrargs.end_key_docid} of
-        {fwd, undefined} -> <<255>>;
-        {rev, undefined} -> <<>>;
-        {_, EKDocId1} -> EKDocId1
-    end,
-
-    Args#mrargs{
-        start_key_docid=SKDocId,
-        end_key_docid=EKDocId
-    }.
-
-
-check_range(#mrargs{start_key=undefined}, _Cmp) ->
-    ok;
-check_range(#mrargs{end_key=undefined}, _Cmp) ->
-    ok;
-check_range(#mrargs{start_key=K, end_key=K}, _Cmp) ->
-    ok;
-check_range(Args, Cmp) ->
-    #mrargs{
-        direction=Dir,
-        start_key=SK,
-        start_key_docid=SKD,
-        end_key=EK,
-        end_key_docid=EKD
-    } = Args,
-    case {Dir, Cmp({SK, SKD}, {EK, EKD})} of
-        {fwd, false} ->
-            throw({query_parse_error,
-                <<"No rows can match your key range, reverse your ",
-                    "start_key and end_key or set descending=true">>});
-        {rev, true} ->
-            throw({query_parse_error,
-                <<"No rows can match your key range, reverse your ",
-                    "start_key and end_key or set descending=false">>});
-        _ -> ok
-    end.
-
-
-view_cmp({_Nth, _Lang, View}) ->
-    view_cmp(View);
-view_cmp(View) ->
-    fun(A, B) -> couch_btree:less(View#mrview.btree, A, B) end.
-
-
-make_header(State) ->
-    #mrst{
-        update_seq=Seq,
-        purge_seq=PurgeSeq,
-        id_btree=IdBtree,
-        log_btree=LogBtree,
-        views=Views
-    } = State,
-
-    ViewStates = lists:foldr(fun(V, Acc) ->
-                    {SeqBtState, KSeqBtState} = case V#mrview.seq_indexed of
-                        true ->
-                            {couch_btree:get_state(V#mrview.seq_btree),
-                             couch_btree:get_state(V#mrview.key_byseq_btree)};
-                        _ -> {nil, nil}
-                    end,
-                    [{couch_btree:get_state(V#mrview.btree),
-                      SeqBtState,
-                      KSeqBtState,
-                      V#mrview.update_seq,
-                      V#mrview.purge_seq} | Acc]
-            end, [], Views),
-
-    LogBtreeState = case LogBtree of
-        nil -> nil;
-        _ -> couch_btree:get_state(LogBtree)
-    end,
-
-    #mrheader{
-        seq=Seq,
-        purge_seq=PurgeSeq,
-        id_btree_state=couch_btree:get_state(IdBtree),
-        log_btree_state= LogBtreeState,
-        view_states=ViewStates
-    }.
-
-
-index_file(DbName, Sig) ->
-    FileName = couch_index_util:hexsig(Sig) ++ ".view",
-    couch_index_util:index_file(mrview, DbName, FileName).
-
-
-compaction_file(DbName, Sig) ->
-    FileName = couch_index_util:hexsig(Sig) ++ ".compact.view",
-    couch_index_util:index_file(mrview, DbName, FileName).
-
-
-open_file(FName) ->
-    case couch_file:open(FName, [nologifmissing]) of
-        {ok, Fd} -> {ok, Fd};
-        {error, enoent} -> couch_file:open(FName, [create]);
-        Error -> Error
-    end.
-
-
-delete_files(DbName, Sig) ->
-    delete_index_file(DbName, Sig),
-    delete_compaction_file(DbName, Sig).
-
-
-delete_index_file(DbName, Sig) ->
-    delete_file(index_file(DbName, Sig)).
-
-
-delete_compaction_file(DbName, Sig) ->
-    delete_file(compaction_file(DbName, Sig)).
-
-
-delete_file(FName) ->
-    case filelib:is_file(FName) of
-        true ->
-            RootDir = couch_index_util:root_dir(),
-            couch_file:delete(RootDir, FName);
-        _ ->
-            ok
-    end.
-
-
-reset_index(Db, Fd, #mrst{sig=Sig}=State) ->
-    ok = couch_file:truncate(Fd, 0),
-    ok = couch_file:write_header(Fd, {Sig, nil}),
-    init_state(Db, Fd, reset_state(State), nil).
-
-
-reset_state(State) ->
-    State#mrst{
-        fd=nil,
-        qserver=nil,
-        seq_indexed=State#mrst.seq_indexed,
-        update_seq=0,
-        id_btree=nil,
-        log_btree=nil,
-        views=[View#mrview{btree=nil, seq_btree=nil,
-                           key_byseq_btree=nil,
-                           seq_indexed=View#mrview.seq_indexed}
-               || View <- State#mrst.views]
-    }.
-
-
-all_docs_key_opts(Args) ->
-    all_docs_key_opts(Args, []).
-
-
-all_docs_key_opts(#mrargs{keys=undefined}=Args, Extra) ->
-    all_docs_key_opts(Args#mrargs{keys=[]}, Extra);
-all_docs_key_opts(#mrargs{keys=[], direction=Dir}=Args, Extra) ->
-    [[{dir, Dir}] ++ ad_skey_opts(Args) ++ ad_ekey_opts(Args) ++ Extra];
-all_docs_key_opts(#mrargs{keys=Keys, direction=Dir}=Args, Extra) ->
-    lists:map(fun(K) ->
-        [{dir, Dir}]
-        ++ ad_skey_opts(Args#mrargs{start_key=K})
-        ++ ad_ekey_opts(Args#mrargs{end_key=K})
-        ++ Extra
-    end, Keys).
-
-
-ad_skey_opts(#mrargs{start_key=SKey}) when is_binary(SKey) ->
-    [{start_key, SKey}];
-ad_skey_opts(#mrargs{start_key_docid=SKeyDocId}) ->
-    [{start_key, SKeyDocId}].
-
-
-ad_ekey_opts(#mrargs{end_key=EKey}=Args) when is_binary(EKey) ->
-    Type = if Args#mrargs.inclusive_end -> end_key; true -> end_key_gt end,
-    [{Type, EKey}];
-ad_ekey_opts(#mrargs{end_key_docid=EKeyDocId}=Args) ->
-    Type = if Args#mrargs.inclusive_end -> end_key; true -> end_key_gt end,
-    [{Type, EKeyDocId}].
-
-
-key_opts(Args) ->
-    key_opts(Args, []).
-
-key_opts(#mrargs{keys=undefined, direction=Dir}=Args, Extra) ->
-    [[{dir, Dir}] ++ skey_opts(Args) ++ ekey_opts(Args) ++ Extra];
-key_opts(#mrargs{keys=Keys, direction=Dir}=Args, Extra) ->
-    lists:map(fun(K) ->
-        [{dir, Dir}]
-        ++ skey_opts(Args#mrargs{start_key=K})
-        ++ ekey_opts(Args#mrargs{end_key=K})
-        ++ Extra
-    end, Keys).
-
-
-skey_opts(#mrargs{start_key=undefined}) ->
-    [];
-skey_opts(#mrargs{start_key=SKey, start_key_docid=SKeyDocId}) ->
-    [{start_key, {SKey, SKeyDocId}}].
-
-
-ekey_opts(#mrargs{end_key=undefined}) ->
-    [];
-ekey_opts(#mrargs{end_key=EKey, end_key_docid=EKeyDocId}=Args) ->
-    case Args#mrargs.inclusive_end of
-        true -> [{end_key, {EKey, EKeyDocId}}];
-        false -> [{end_key_gt, {EKey, reverse_key_default(EKeyDocId)}}]
-    end.
-
-
-reverse_key_default(<<>>) -> <<255>>;
-reverse_key_default(<<255>>) -> <<>>;
-reverse_key_default(Key) -> Key.
-
-
-changes_key_opts(StartSeq, Args) ->
-    changes_key_opts(StartSeq, Args, []).
-
-
-changes_key_opts(StartSeq, #mrargs{keys=undefined, direction=Dir}=Args, Extra) ->
-    [[{dir, Dir}] ++ changes_skey_opts(StartSeq, Args) ++
-     changes_ekey_opts(StartSeq, Args) ++ Extra];
-changes_key_opts(StartSeq, #mrargs{keys=Keys, direction=Dir}=Args, Extra) ->
-    lists:map(fun(K) ->
-        [{dir, Dir}]
-        ++ changes_skey_opts(StartSeq, Args#mrargs{start_key=K})
-        ++ changes_ekey_opts(StartSeq, Args#mrargs{end_key=K})
-        ++ Extra
-    end, Keys).
-
-
-changes_skey_opts(StartSeq, #mrargs{start_key=undefined}) ->
-    [{start_key, [<<>>, StartSeq+1]}];
-changes_skey_opts(StartSeq, #mrargs{start_key=SKey,
-                                    start_key_docid=SKeyDocId}) ->
-    [{start_key, {[SKey, StartSeq+1], SKeyDocId}}].
-
-
-changes_ekey_opts(_StartSeq, #mrargs{end_key=undefined}) ->
-    [];
-changes_ekey_opts(_StartSeq, #mrargs{end_key=EKey,
-                                    end_key_docid=EKeyDocId,
-                                    direction=Dir}=Args) ->
-    EndSeq = case Dir of
-        fwd -> 16#10000000;
-        rev -> 0
-    end,
-
-    case Args#mrargs.inclusive_end of
-        true -> [{end_key, {[EKey, EndSeq], EKeyDocId}}];
-        false -> [{end_key_gt, {[EKey, EndSeq], EKeyDocId}}]
-    end.
-
-
-
-calculate_data_size(IdBt, LogBt, Views) ->
-    SumFun = fun
-        (#mrview{btree=Bt, seq_btree=nil}, Acc) ->
-            sum_btree_sizes(Acc, couch_btree:size(Bt));
-        (#mrview{btree=Bt, seq_btree=SBt, key_byseq_btree=KSBt}, Acc) ->
-            Acc1 = sum_btree_sizes(Acc, couch_btree:size(Bt)),
-            Acc2 = sum_btree_sizes(Acc1, couch_btree:size(SBt)),
-            sum_btree_sizes(Acc2, couch_btree:size(KSBt))
-    end,
-    Size = case LogBt of
-        nil ->
-            lists:foldl(SumFun, couch_btree:size(IdBt), Views);
-        _ ->
-            lists:foldl(SumFun, couch_btree:size(IdBt) +
-                        couch_btree:size(LogBt), Views)
-    end,
-    {ok, Size}.
-
-
-sum_btree_sizes(nil, _) ->
-    null;
-sum_btree_sizes(_, nil) ->
-    null;
-sum_btree_sizes(Size1, Size2) ->
-    Size1 + Size2.
-
-
-detuple_kvs([], Acc) ->
-    lists:reverse(Acc);
-detuple_kvs([KV | Rest], Acc) ->
-    {{Key,Id},Value} = KV,
-    NKV = [[Key, Id], Value],
-    detuple_kvs(Rest, [NKV | Acc]).
-
-
-expand_dups([], Acc) ->
-    lists:reverse(Acc);
-expand_dups([{Key, {dups, Vals}} | Rest], Acc) ->
-    Expanded = [{Key, Val} || Val <- Vals],
-    expand_dups(Rest, Expanded ++ Acc);
-expand_dups([KV | Rest], Acc) ->
-    expand_dups(Rest, [KV | Acc]).
-
-
-changes_expand_dups([], Acc) ->
-    lists:reverse(Acc);
-changes_expand_dups([{{[Key, Seq], DocId}, {dups, Vals}} | Rest], Acc) ->
-    Expanded = [{{Seq, Key, DocId}, Val} || Val <- Vals],
-    changes_expand_dups(Rest, Expanded ++ Acc);
-changes_expand_dups([{{Seq, Key}, {DocId, {dups, Vals}}} | Rest], Acc) ->
-    Expanded = [{{Seq, Key, DocId}, Val} || Val <- Vals],
-    changes_expand_dups(Rest, Expanded ++ Acc);
-changes_expand_dups([{{[Key, Seq], DocId}, Val} | Rest], Acc) ->
-    changes_expand_dups(Rest, [{{Seq, Key, DocId}, Val} | Acc]);
-changes_expand_dups([{{Seq, Key}, {DocId, Val}} | Rest], Acc) ->
-    changes_expand_dups(Rest, [{{Seq, Key, DocId}, Val} | Acc]).
-
-maybe_load_doc(_Db, _DI, #mrargs{include_docs=false}) ->
-    [];
-maybe_load_doc(Db, #doc_info{}=DI, #mrargs{conflicts=true, doc_options=Opts}) ->
-    doc_row(couch_index_util:load_doc(Db, DI, [conflicts]), Opts);
-maybe_load_doc(Db, #doc_info{}=DI, #mrargs{doc_options=Opts}) ->
-    doc_row(couch_index_util:load_doc(Db, DI, []), Opts).
-
-
-maybe_load_doc(_Db, _Id, _Val, #mrargs{include_docs=false}) ->
-    [];
-maybe_load_doc(Db, Id, Val, #mrargs{conflicts=true, doc_options=Opts}) ->
-    doc_row(couch_index_util:load_doc(Db, docid_rev(Id, Val), [conflicts]), Opts);
-maybe_load_doc(Db, Id, Val, #mrargs{doc_options=Opts}) ->
-    doc_row(couch_index_util:load_doc(Db, docid_rev(Id, Val), []), Opts).
-
-
-doc_row(null, _Opts) ->
-    [{doc, null}];
-doc_row(Doc, Opts) ->
-    [{doc, couch_doc:to_json_obj(Doc, Opts)}].
-
-
-docid_rev(Id, {Props}) ->
-    DocId = couch_util:get_value(<<"_id">>, Props, Id),
-    Rev = case couch_util:get_value(<<"_rev">>, Props, nil) of
-        nil -> nil;
-        Rev0 -> couch_doc:parse_rev(Rev0)
-    end,
-    {DocId, Rev};
-docid_rev(Id, _) ->
-    {Id, nil}.
-
-
-index_of(Key, List) ->
-    index_of(Key, List, 1).
-
-
-index_of(_, [], _) ->
-    throw({error, missing_named_view});
-index_of(Key, [Key | _], Idx) ->
-    Idx;
-index_of(Key, [_ | Rest], Idx) ->
-    index_of(Key, Rest, Idx+1).
-
-
-mrverror(Mesg) ->
-    throw({query_parse_error, Mesg}).
-
-
-to_key_seq(L) ->
-    [{{[Key, Seq], DocId}, Val} || {{Seq, Key}, {DocId, Val}} <- L].
-
-%% Updates 1.2.x or earlier view files to 1.3.x or later view files
-%% transparently, the first time the 1.2.x view file is opened by
-%% 1.3.x or later.
-%%
-%% Here's how it works:
-%%
-%% Before opening a view index,
-%% If no matching index file is found in the new location:
-%%  calculate the <= 1.2.x view signature
-%%  if a file with that signature lives in the old location
-%%    rename it to the new location with the new signature in the name.
-%% Then proceed to open the view index as usual.
-%% After opening, read its header.
-%%
-%% If the header matches the <= 1.2.x style #index_header record:
-%%   upgrade the header to the new #mrheader record
-%% The next time the view is used, the new header is used.
-%%
-%% If we crash after the rename, but before the header upgrade,
-%%   the header upgrade is done on the next view opening.
-%%
-%% If we crash between upgrading to the new header and writing
-%%   that header to disk, we start with the old header again,
-%%   do the upgrade and write to disk.
-
-maybe_update_index_file(State) ->
-    DbName = State#mrst.db_name,
-    NewIndexFile = index_file(DbName, State#mrst.sig),
-    % open in read-only mode so we don't create
-    % the file if it doesn't exist.
-    case file:open(NewIndexFile, [read, raw]) of
-    {ok, Fd_Read} ->
-        % the new index file exists, there is nothing to do here.
-        file:close(Fd_Read);
-    _Error ->
-        update_index_file(State)
-    end.
-
-update_index_file(State) ->
-    Sig = sig_vsn_12x(State),
-    DbName = State#mrst.db_name,
-    FileName = couch_index_util:hexsig(Sig) ++ ".view",
-    IndexFile = couch_index_util:index_file("", DbName, FileName),
-
-    % If we have an old index, rename it to the new position.
-    case file:read_file_info(IndexFile) of
-    {ok, _FileInfo} ->
-        % Crash if the rename fails for any reason.
-        % If the target exists, e.g. the next request will find the
-        % new file and we are good. We might need to catch this
-        % further up to avoid a full server crash.
-        ?LOG_INFO("Attempting to update legacy view index file.", []),
-        NewIndexFile = index_file(DbName, State#mrst.sig),
-        ok = filelib:ensure_dir(NewIndexFile),
-        ok = file:rename(IndexFile, NewIndexFile),
-        ?LOG_INFO("Successfully updated legacy view index file.", []),
-        Sig;
-    _ ->
-        % Ignore missing index file
-        ok
-    end.
-
-sig_vsn_12x(State) ->
-    ViewInfo = [old_view_format(V) || V <- State#mrst.views],
-    SigData = case State#mrst.lib of
-    {[]} ->
-        {ViewInfo, State#mrst.language, State#mrst.design_opts};
-    _ ->
-        {ViewInfo, State#mrst.language, State#mrst.design_opts,
-            couch_index_util:sort_lib(State#mrst.lib)}
-    end,
-    couch_util:md5(term_to_binary(SigData)).
-
-old_view_format(View) ->
-{
-    view,
-    View#mrview.id_num,
-    View#mrview.map_names,
-    View#mrview.def,
-    View#mrview.btree,
-    View#mrview.reduce_funs,
-    View#mrview.options
-}.
-
-%% End of <= 1.2.x upgrade code.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/test/01-load.t
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/test/01-load.t b/apps/couch_mrview/test/01-load.t
deleted file mode 100644
index cd49785..0000000
--- a/apps/couch_mrview/test/01-load.t
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
-
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-% Test that we can load each module.
-
-main(_) ->
-    test_util:init_code_path(),
-    Modules = [
-        couch_mrview,
-        couch_mrview_compactor,
-        couch_mrview_http,
-        couch_mrview_index,
-        couch_mrview_updater,
-        couch_mrview_util
-    ],
-
-    etap:plan(length(Modules)),
-    lists:foreach(
-        fun(Module) ->
-            etap:loaded_ok(Module, lists:concat(["Loaded: ", Module]))
-        end, Modules),
-    etap:end_tests().

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/test/02-map-views.t
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/test/02-map-views.t b/apps/couch_mrview/test/02-map-views.t
deleted file mode 100644
index 4f87193..0000000
--- a/apps/couch_mrview/test/02-map-views.t
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
-
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-main(_) ->
-    etap:plan(6),
-    case (catch test()) of
-        ok ->
-            etap:end_tests();
-        Other ->
-            etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
-            etap:bail(Other)
-    end,
-    timer:sleep(300),
-    ok.
-
-test() ->
-    test_util:start_couch(),
-
-    {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
-
-    test_basic(Db),
-    test_range(Db),
-    test_rev_range(Db),
-    test_limit_and_skip(Db),
-    test_include_docs(Db),
-    test_empty_view(Db),
-
-    test_util:stop_couch(),
-    ok.
-
-
-test_basic(Db) ->
-    Result = run_query(Db, []),
-    Expect = {ok, [
-        {meta, [{total, 10}, {offset, 0}]},
-        {row, [{id, <<"1">>}, {key, 1}, {value, 1}]},
-        {row, [{id, <<"2">>}, {key, 2}, {value, 2}]},
-        {row, [{id, <<"3">>}, {key, 3}, {value, 3}]},
-        {row, [{id, <<"4">>}, {key, 4}, {value, 4}]},
-        {row, [{id, <<"5">>}, {key, 5}, {value, 5}]},
-        {row, [{id, <<"6">>}, {key, 6}, {value, 6}]},
-        {row, [{id, <<"7">>}, {key, 7}, {value, 7}]},
-        {row, [{id, <<"8">>}, {key, 8}, {value, 8}]},
-        {row, [{id, <<"9">>}, {key, 9}, {value, 9}]},
-        {row, [{id, <<"10">>}, {key, 10}, {value, 10}]}
-    ]},
-    etap:is(Result, Expect, "Simple view query worked.").
-
-
-test_range(Db) ->
-    Result = run_query(Db, [{start_key, 3}, {end_key, 5}]),
-    Expect = {ok, [
-        {meta, [{total, 10}, {offset, 2}]},
-        {row, [{id, <<"3">>}, {key, 3}, {value, 3}]},
-        {row, [{id, <<"4">>}, {key, 4}, {value, 4}]},
-        {row, [{id, <<"5">>}, {key, 5}, {value, 5}]}
-    ]},
-    etap:is(Result, Expect, "Query with range works.").
-
-
-test_rev_range(Db) ->
-    Result = run_query(Db, [
-        {direction, rev},
-        {start_key, 5}, {end_key, 3},
-        {inclusive_end, true}
-    ]),
-    Expect = {ok, [
-        {meta, [{total, 10}, {offset, 5}]},
-        {row, [{id, <<"5">>}, {key, 5}, {value, 5}]},
-        {row, [{id, <<"4">>}, {key, 4}, {value, 4}]},
-        {row, [{id, <<"3">>}, {key, 3}, {value, 3}]}
-    ]},
-    etap:is(Result, Expect, "Query with reversed range works.").
-
-
-test_limit_and_skip(Db) ->
-    Result = run_query(Db, [
-        {start_key, 2},
-        {limit, 3},
-        {skip, 3}
-    ]),
-    Expect = {ok, [
-        {meta, [{total, 10}, {offset, 4}]},
-        {row, [{id, <<"5">>}, {key, 5}, {value, 5}]},
-        {row, [{id, <<"6">>}, {key, 6}, {value, 6}]},
-        {row, [{id, <<"7">>}, {key, 7}, {value, 7}]}
-    ]},
-    etap:is(Result, Expect, "Query with limit and skip works.").
-
-
-test_include_docs(Db) ->
-    Result = run_query(Db, [
-        {start_key, 8},
-        {end_key, 8},
-        {include_docs, true}
-    ]),
-    Doc = {[
-        {<<"_id">>,<<"8">>},
-        {<<"_rev">>, <<"1-55b9a29311341e07ec0a7ca13bc1b59f">>},
-        {<<"val">>,8}
-    ]},
-    Expect = {ok, [
-        {meta, [{total, 10}, {offset, 7}]},
-        {row, [{id, <<"8">>}, {key, 8}, {value, 8}, {doc, Doc}]}
-    ]},
-    etap:is(Result, Expect, "Query with include docs works.").
-
-
-test_empty_view(Db) ->
-    Result = couch_mrview:query_view(Db, <<"_design/bar">>, <<"bing">>),
-    Expect = {ok, [
-        {meta, [{total, 0}, {offset, 0}]}
-    ]},
-    etap:is(Result, Expect, "Empty views are correct.").
-
-
-run_query(Db, Opts) ->
-    couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>, Opts).

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/test/03-red-views.t
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/test/03-red-views.t b/apps/couch_mrview/test/03-red-views.t
deleted file mode 100644
index 594fdfd..0000000
--- a/apps/couch_mrview/test/03-red-views.t
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
-
-
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-main(_) ->
-    test_util:run(4, fun() -> test() end).
-
-test() ->
-    test_util:start_couch(),
-
-    {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, red),
-
-    test_basic(Db),
-    test_key_range(Db),
-    test_group_level(Db),
-    test_group_exact(Db),
-
-    test_util:stop_couch(),
-    ok.
-
-
-test_basic(Db) ->
-    Result = run_query(Db, []),
-    Expect = {ok, [
-        {meta, []},
-        {row, [{key, null}, {value, 55}]}
-    ]},
-    etap:is(Result, Expect, "Simple reduce view works.").
-
-
-test_key_range(Db) ->
-    Result = run_query(Db, [{start_key, [0, 2]}, {end_key, [0, 4]}]),
-    Expect = {ok, [
-        {meta, []},
-        {row, [{key, null}, {value, 6}]}
-    ]},
-    etap:is(Result, Expect, "Reduce with key range works.").
-
-
-test_group_level(Db) ->
-    Result = run_query(Db, [{group_level, 1}]),
-    Expect = {ok, [
-        {meta, []},
-        {row, [{key, [0]}, {value, 30}]},
-        {row, [{key, [1]}, {value, 25}]}
-    ]},
-    etap:is(Result, Expect, "Group level works.").
-
-test_group_exact(Db) ->
-    Result = run_query(Db, [{group_level, exact}]),
-    Expect = {ok, [
-        {meta, []},
-        {row, [{key, [0, 2]}, {value, 2}]},
-        {row, [{key, [0, 4]}, {value, 4}]},
-        {row, [{key, [0, 6]}, {value, 6}]},
-        {row, [{key, [0, 8]}, {value, 8}]},
-        {row, [{key, [0, 10]}, {value, 10}]},
-        {row, [{key, [1, 1]}, {value, 1}]},
-        {row, [{key, [1, 3]}, {value, 3}]},
-        {row, [{key, [1, 5]}, {value, 5}]},
-        {row, [{key, [1, 7]}, {value, 7}]},
-        {row, [{key, [1, 9]}, {value, 9}]}
-    ]},
-    etap:is(Result, Expect, "Group exact works.").
-
-
-run_query(Db, Opts) ->
-    couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>, Opts).

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/test/04-index-info.t
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/test/04-index-info.t b/apps/couch_mrview/test/04-index-info.t
deleted file mode 100644
index e95db1c..0000000
--- a/apps/couch_mrview/test/04-index-info.t
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
-
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-main(_) ->
-    etap:plan(12),
-    case (catch test()) of
-        ok ->
-            etap:end_tests();
-        Other ->
-            etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
-            etap:bail(Other)
-    end,
-    timer:sleep(300),
-    ok.
-
-sig() -> <<"fdf04ef29c4a471f150acad075bdf47f">>.
-
-test() ->
-    test_util:start_couch(),
-
-    {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
-    couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>),
-
-    {ok, Info} = couch_mrview:get_info(Db, <<"_design/bar">>),
-
-    etap:is(getval(signature, Info), sig(), "Signature is ok."),
-    etap:is(getval(language, Info), <<"javascript">>, "Language is ok."),
-    etap:is_greater(getval(disk_size, Info), 0, "Disk size is ok."),
-    etap:is_greater(getval(data_size, Info), 0, "Data size is ok."),
-    etap:is(getval(update_seq, Info), 11, "Update seq is ok."),
-    etap:is(getval(purge_seq, Info), 0, "Purge seq is ok."),
-    etap:is(getval(updater_running, Info), false, "No updater running."),
-    etap:is(getval(compact_running, Info), false, "No compaction running."),
-    etap:is(getval(waiting_clients, Info), 0, "No waiting clients."),
-
-
-    {ok, ViewInfo} = couch_mrview:get_view_info(Db, <<"_design/bar">>,
-                                           <<"baz">>),
-    etap:is(getval(update_seq, ViewInfo), 11, "View Update seq is ok."),
-    etap:is(getval(purge_seq, ViewInfo), 0, "View Update seq is ok."),
-    etap:is(getval(total_rows, ViewInfo), 10, "View total rows is ok."),
-
-
-    test_util:stop_couch(),
-    ok.
-
-getval(Key, PL) ->
-    {value, {Key, Val}} = lists:keysearch(Key, 1, PL),
-    Val.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/test/05-collation.t
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/test/05-collation.t b/apps/couch_mrview/test/05-collation.t
deleted file mode 100644
index 1ebbe9c..0000000
--- a/apps/couch_mrview/test/05-collation.t
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
-
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-main(_) ->
-    test_util:run(9, fun() -> test() end).
-
-
-test() ->
-    test_util:start_couch(),
-
-    {ok, Db0} = couch_mrview_test_util:new_db(<<"foo">>, map),
-    {ok, Db1} = couch_mrview_test_util:save_docs(Db0, docs()),
-
-    test_collated_fwd(Db1),
-    test_collated_rev(Db1),
-    test_range_collation(Db1),
-    test_inclusive_end(Db1),
-    test_uninclusive_end(Db1),
-    test_with_endkey_docid(Db1),
-
-    test_util:stop_couch(),
-    ok.
-
-test_collated_fwd(Db) ->
-    {ok, Results} = run_query(Db, []),
-    Expect = [{meta, [{total, 26}, {offset, 0}]}] ++ rows(),
-    etap:is(Results, Expect, "Values were collated correctly.").
-
-
-test_collated_rev(Db) ->
-    {ok, Results} = run_query(Db, [{direction, rev}]),
-    Expect = [{meta, [{total, 26}, {offset, 0}]}] ++ lists:reverse(rows()),
-    etap:is(Results, Expect, "Values were collated correctly descending.").
-
-
-test_range_collation(Db) ->
-    {_, Error} = lists:foldl(fun(V, {Count, Error}) ->
-        {ok, Results} = run_query(Db, [{start_key, V}, {end_key, V}]),
-        Id = list_to_binary(integer_to_list(Count)),
-        Expect = [
-            {meta, [{total, 26}, {offset, Count}]},
-            {row, [{id, Id}, {key, V}, {value, 0}]}
-        ],
-        case Results == Expect of
-            true -> {Count+1, Error};
-            _ -> {Count+1, true}
-        end
-    end, {0, false}, vals()),
-    etap:is(Error, false, "Found each individual key correctly.").
-
-
-test_inclusive_end(Db) ->
-    Opts = [{end_key, <<"b">>}, {inclusive_end, true}],
-    {ok, Rows0} = run_query(Db, Opts),
-    LastRow0 = lists:last(Rows0),
-    Expect0 = {row, [{id,<<"10">>}, {key,<<"b">>}, {value,0}]},
-    etap:is(LastRow0, Expect0, "Inclusive end is correct."),
-
-    {ok, Rows1} = run_query(Db, Opts ++ [{direction, rev}]),
-    LastRow1 = lists:last(Rows1),
-    Expect1 = {row, [{id,<<"10">>}, {key,<<"b">>}, {value,0}]},
-    etap:is(LastRow1, Expect1,
-            "Inclusive end is correct with descending=true").
-
-test_uninclusive_end(Db) ->
-    Opts = [{end_key, <<"b">>}, {inclusive_end, false}],
-    {ok, Rows0} = run_query(Db, Opts),
-    LastRow0 = lists:last(Rows0),
-    Expect0 = {row, [{id,<<"9">>}, {key,<<"aa">>}, {value,0}]},
-    etap:is(LastRow0, Expect0, "Uninclusive end is correct."),
-
-    {ok, Rows1} = run_query(Db, Opts ++ [{direction, rev}]),
-    LastRow1 = lists:last(Rows1),
-    Expect1 = {row, [{id,<<"11">>}, {key,<<"B">>}, {value,0}]},
-    etap:is(LastRow1, Expect1,
-            "Uninclusive end is correct with descending=true").
-
-
-test_with_endkey_docid(Db) ->
-    {ok, Rows0} = run_query(Db, [
-        {end_key, <<"b">>}, {end_key_docid, <<"10">>},
-        {inclusive_end, false}
-    ]),
-    Result0 = lists:last(Rows0),
-    Expect0 = {row, [{id,<<"9">>}, {key,<<"aa">>}, {value,0}]},
-    etap:is(Result0, Expect0, "Uninclsuive end with endkey_docid set is ok."),
-
-    {ok, Rows1} = run_query(Db, [
-        {end_key, <<"b">>}, {end_key_docid, <<"11">>},
-        {inclusive_end, false}
-    ]),
-    Result1 = lists:last(Rows1),
-    Expect1 = {row, [{id,<<"10">>}, {key,<<"b">>}, {value,0}]},
-    etap:is(Result1, Expect1, "Uninclsuive end with endkey_docid set is ok.").
-
-
-run_query(Db, Opts) ->
-    couch_mrview:query_view(Db, <<"_design/bar">>, <<"zing">>, Opts).
-
-
-docs() ->
-    {Docs, _} = lists:foldl(fun(V, {Docs0, Count}) ->
-        Doc = couch_doc:from_json_obj({[
-            {<<"_id">>, list_to_binary(integer_to_list(Count))},
-            {<<"foo">>, V}
-        ]}),
-        {[Doc | Docs0], Count+1}
-    end, {[], 0}, vals()),
-    Docs.
-
-
-rows() ->
-    {Rows, _} = lists:foldl(fun(V, {Rows0, Count}) ->
-        Id = list_to_binary(integer_to_list(Count)),
-        Row = {row, [{id, Id}, {key, V}, {value, 0}]},
-        {[Row | Rows0], Count+1}
-    end, {[], 0}, vals()),
-    lists:reverse(Rows).
-
-
-vals() ->
-    [
-        null,
-        false,
-        true,
-
-        1,
-        2,
-        3.0,
-        4,
-
-        <<"a">>,
-        <<"A">>,
-        <<"aa">>,
-        <<"b">>,
-        <<"B">>,
-        <<"ba">>,
-        <<"bb">>,
-
-        [<<"a">>],
-        [<<"b">>],
-        [<<"b">>, <<"c">>],
-        [<<"b">>, <<"c">>, <<"a">>],
-        [<<"b">>, <<"d">>],
-        [<<"b">>, <<"d">>, <<"e">>],
-
-        {[{<<"a">>, 1}]},
-        {[{<<"a">>, 2}]},
-        {[{<<"b">>, 1}]},
-        {[{<<"b">>, 2}]},
-        {[{<<"b">>, 2}, {<<"a">>, 1}]},
-        {[{<<"b">>, 2}, {<<"c">>, 2}]}
-    ].

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/test/06-all-docs.t
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/test/06-all-docs.t b/apps/couch_mrview/test/06-all-docs.t
deleted file mode 100644
index 0916568..0000000
--- a/apps/couch_mrview/test/06-all-docs.t
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
-
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-main(_) ->
-    test_util:run(6, fun() -> test() end).
-
-
-test() ->
-    test_util:start_couch(),
-
-    {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map),
-
-    test_basic(Db),
-    test_range(Db),
-    test_rev_range(Db),
-    test_limit_and_skip(Db),
-    test_include_docs(Db),
-    test_empty_view(Db),
-
-    test_util:stop_couch(),
-    ok.
-
-
-test_basic(Db) ->
-    Result = run_query(Db, []),
-    Expect = {ok, [
-        {meta, [{total, 11}, {offset, 0}]},
-        mk_row(<<"1">>, <<"1-08d53a5760b95fce6df2e2c5b008be39">>),
-        mk_row(<<"10">>, <<"1-a05b6ea2bc0243949f103d5b4f15f71e">>),
-        mk_row(<<"2">>, <<"1-b57c77a9e6f7574ca6469f0d6dcd78bb">>),
-        mk_row(<<"3">>, <<"1-7fbf84d56f8017880974402d60f5acd6">>),
-        mk_row(<<"4">>, <<"1-fcaf5852c08ffb239ac8ce16c409f253">>),
-        mk_row(<<"5">>, <<"1-aaac5d460fd40f9286e57b9bf12e23d2">>),
-        mk_row(<<"6">>, <<"1-aca21c2e7bc5f8951424fcfc5d1209d8">>),
-        mk_row(<<"7">>, <<"1-4374aeec17590d82f16e70f318116ad9">>),
-        mk_row(<<"8">>, <<"1-55b9a29311341e07ec0a7ca13bc1b59f">>),
-        mk_row(<<"9">>, <<"1-558c8487d9aee25399a91b5d31d90fe2">>),
-        mk_row(<<"_design/bar">>, <<"1-a44e1dd1994a7717bf89c894ebd1f081">>)
-    ]},
-    etap:is(Result, Expect, "Simple view query worked.").
-
-
-test_range(Db) ->
-    Result = run_query(Db, [{start_key, <<"3">>}, {end_key, <<"5">>}]),
-    Expect = {ok, [
-        {meta, [{total, 11}, {offset, 3}]},
-        mk_row(<<"3">>, <<"1-7fbf84d56f8017880974402d60f5acd6">>),
-        mk_row(<<"4">>, <<"1-fcaf5852c08ffb239ac8ce16c409f253">>),
-        mk_row(<<"5">>, <<"1-aaac5d460fd40f9286e57b9bf12e23d2">>)
-    ]},
-    etap:is(Result, Expect, "Query with range works.").
-
-
-test_rev_range(Db) ->
-    Result = run_query(Db, [
-        {direction, rev},
-        {start_key, <<"5">>}, {end_key, <<"3">>},
-        {inclusive_end, true}
-    ]),
-    Expect = {ok, [
-        {meta, [{total, 11}, {offset, 5}]},
-        mk_row(<<"5">>, <<"1-aaac5d460fd40f9286e57b9bf12e23d2">>),
-        mk_row(<<"4">>, <<"1-fcaf5852c08ffb239ac8ce16c409f253">>),
-        mk_row(<<"3">>, <<"1-7fbf84d56f8017880974402d60f5acd6">>)
-    ]},
-    etap:is(Result, Expect, "Query with reversed range works.").
-
-
-test_limit_and_skip(Db) ->
-    Result = run_query(Db, [
-        {start_key, <<"2">>},
-        {limit, 3},
-        {skip, 3}
-    ]),
-    Expect = {ok, [
-        {meta, [{total, 11}, {offset, 5}]},
-        mk_row(<<"5">>, <<"1-aaac5d460fd40f9286e57b9bf12e23d2">>),
-        mk_row(<<"6">>, <<"1-aca21c2e7bc5f8951424fcfc5d1209d8">>),
-        mk_row(<<"7">>, <<"1-4374aeec17590d82f16e70f318116ad9">>)
-    ]},
-    etap:is(Result, Expect, "Query with limit and skip works.").
-
-
-test_include_docs(Db) ->
-    Result = run_query(Db, [
-        {start_key, <<"8">>},
-        {end_key, <<"8">>},
-        {include_docs, true}
-    ]),
-    Doc = {[
-        {<<"_id">>,<<"8">>},
-        {<<"_rev">>, <<"1-55b9a29311341e07ec0a7ca13bc1b59f">>},
-        {<<"val">>, 8}
-    ]},
-    Val = {[{rev, <<"1-55b9a29311341e07ec0a7ca13bc1b59f">>}]},
-    Expect = {ok, [
-        {meta, [{total, 11}, {offset, 8}]},
-        {row, [{id, <<"8">>}, {key, <<"8">>}, {value, Val}, {doc, Doc}]}
-    ]},
-    etap:is(Result, Expect, "Query with include docs works.").
-
-
-test_empty_view(Db) ->
-    Result = couch_mrview:query_view(Db, <<"_design/bar">>, <<"bing">>),
-    Expect = {ok, [
-        {meta, [{total, 0}, {offset, 0}]}
-    ]},
-    etap:is(Result, Expect, "Empty views are correct.").
-
-
-mk_row(Id, Rev) ->
-    {row, [{id, Id}, {key, Id}, {value, {[{rev, Rev}]}}]}.
-
-
-run_query(Db, Opts) ->
-    couch_mrview:query_all_docs(Db, Opts).

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/test/07-compact-swap.t
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/test/07-compact-swap.t b/apps/couch_mrview/test/07-compact-swap.t
deleted file mode 100644
index ba8e438..0000000
--- a/apps/couch_mrview/test/07-compact-swap.t
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
-
-
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-main(_) ->
-    test_util:run(1, fun() -> test() end).
-
-
-test() ->
-    test_util:start_couch(),
-
-    {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, map, 1000),
-    couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>),
-    test_swap(Db),
-
-    test_util:stop_couch(),
-    ok.
-
-
-test_swap(Db) ->
-    {ok, QPid} = start_query(Db),
-    {ok, MonRef} = couch_mrview:compact(Db, <<"_design/bar">>, [monitor]),
-    receive
-        {'DOWN', MonRef, process, _, _} -> ok
-    after 1000 ->
-        throw(compaction_failed)
-    end,
-    QPid ! {self(), continue},
-    receive
-        {QPid, Count} ->
-            etap:is(Count, 1000, "View finished successfully.")
-    after 1000 ->
-        throw("query failed")
-    end.
-
-
-start_query(Db) ->
-    Self = self(),
-    Pid = spawn(fun() ->
-        CB = fun
-            (_, wait) -> receive {Self, continue} -> {ok, 0} end;
-            ({row, _}, Count) -> {ok, Count+1};
-            (_, Count) -> {ok, Count}
-        end,
-        {ok, Result} =
-        couch_mrview:query_view(Db, <<"_design/bar">>, <<"baz">>, [], CB, wait),
-        Self ! {self(), Result}
-    end),
-    {ok, Pid}.

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/test/08-changes_since.t
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/test/08-changes_since.t b/apps/couch_mrview/test/08-changes_since.t
deleted file mode 100644
index 58c92e9..0000000
--- a/apps/couch_mrview/test/08-changes_since.t
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
-
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-main(_) ->
-    etap:plan(14),
-    case (catch test()) of
-        ok ->
-            etap:end_tests();
-        Other ->
-            etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
-            etap:bail(Other)
-    end,
-    timer:sleep(300),
-    ok.
-
-test() ->
-    test_util:start_couch(),
-
-    {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, changes),
-
-    test_basic(Db),
-    test_range(Db),
-    test_basic_since(Db),
-    test_range_since(Db),
-    test_basic_count(Db),
-    test_range_count(Db),
-    test_basic_count_since(Db),
-    test_range_count_since(Db),
-    test_compact(Db),
-    test_remove_key(Db),
-    catch test_util:stop_couch(),
-    ok.
-
-
-test_basic(Db) ->
-    Result = run_query(Db, 0, []),
-    Expect = {ok, [
-                {{2, 1, <<"1">>}, 1},
-                {{3, 10, <<"10">>}, 10},
-                {{4, 2, <<"2">>}, 2},
-                {{5, 3, <<"3">>}, 3},
-                {{6, 4, <<"4">>}, 4},
-                {{7, 5, <<"5">>}, 5},
-                {{8, 6, <<"6">>}, 6},
-                {{9, 7, <<"7">>}, 7},
-                {{10, 8, <<"8">>}, 8},
-                {{11, 9, <<"9">>}, 9}
-    ]},
-    etap:is(Result, Expect, "Simple view query worked.").
-
-
-test_range(Db) ->
-    Result = run_query(Db, 0, [{start_key, 3}, {end_key, 5}]),
-    Expect = {ok, [
-                {{5, 3, <<"3">>}, 3},
-                {{6, 4, <<"4">>}, 4},
-                {{7, 5, <<"5">>}, 5}
-    ]},
-    etap:is(Result, Expect, "Query with range works.").
-
-test_basic_since(Db) ->
-    Result = run_query(Db, 5, []),
-    Expect = {ok, [
-                {{6, 4, <<"4">>}, 4},
-                {{7, 5, <<"5">>}, 5},
-                {{8, 6, <<"6">>}, 6},
-                {{9, 7, <<"7">>}, 7},
-                {{10, 8, <<"8">>}, 8},
-                {{11, 9, <<"9">>}, 9}
-    ]},
-    etap:is(Result, Expect, "Simple view query since 5 worked.").
-
-test_range_since(Db) ->
-    Result = run_query(Db, 5, [{start_key, 3}, {end_key, 5}]),
-    Expect = {ok, [
-                {{6, 4, <<"4">>}, 4},
-                {{7, 5, <<"5">>}, 5}
-    ]},
-    etap:is(Result, Expect, "Query with range since 5 works.").
-
-test_basic_count(Db) ->
-    Result = run_count_query(Db, 0, []),
-    etap:is(Result, 10, "Simple view count worked.").
-
-test_range_count(Db) ->
-    Result = run_count_query(Db, 0, [{start_key, 3}, {end_key, 5}]),
-    etap:is(Result, 3, "Count with range works.").
-
-test_basic_count_since(Db) ->
-    Result = run_count_query(Db, 5, []),
-    etap:is(Result, 6, "Simple view count since 5 worked.").
-
-test_range_count_since(Db) ->
-    Result = run_count_query(Db, 5, [{start_key, 3}, {end_key, 5}]),
-    etap:is(Result, 2, "Count with range since 5 works.").
-
-test_compact(Db) ->
-    Result = couch_mrview:compact(Db, <<"_design/bar">>),
-    etap:is(Result, ok, "compact view is OK"),
-    Count = run_count_query(Db, 0, []),
-    etap:is(Count, 10, "compact view worked.").
-
-test_remove_key(Db) ->
-    %% add new doc
-    Doc = couch_mrview_test_util:doc(11),
-    {ok, Rev} = couch_db:update_doc(Db, Doc, []),
-    RevStr = couch_doc:rev_to_str(Rev),
-    {ok, _} =  couch_db:ensure_full_commit(Db),
-    {ok, Db1} = couch_db:reopen(Db),
-    Result = run_count_query(Db1, 0, []),
-    etap:is(Result, 11, "Add new doc worked."),
-    %% check new view key
-    Result1 = run_query(Db1, 0, [{start_key, 11}, {end_key, 11}]),
-    Expect = {ok, [
-                {{12, 11, <<"11">>}, 11}
-    ]},
-    etap:is(Result1, Expect, "added key OK."),
-
-    %% delete doc
-    Doc2 = couch_doc:from_json_obj({[
-                {<<"_id">>, <<"11">>},
-                {<<"_rev">>, RevStr},
-                {<<"_deleted">>, true}
-    ]}),
-    {ok, _} = couch_db:update_doc(Db1, Doc2, []),
-    {ok, Db2} = couch_db:reopen(Db1),
-    Result2 = run_count_query(Db2, 0, []),
-    etap:is(Result2, 11, "removed key saved."),
-    %% check new view key
-    Result3 = run_query(Db2, 0, [{start_key, 11}, {end_key, 11}]),
-    Expect2 = {ok, [
-                {{13, 11, <<"11">>}, {[{<<"_removed">>, true}]}}
-    ]},
-    etap:is(Result3, Expect2, "removed key OK.").
-
-run_query(Db, Since, Opts) ->
-    Fun = fun(KV, Acc) -> {ok, [KV | Acc]} end,
-    {ok, R} = couch_mrview:view_changes_since(Db, <<"_design/bar">>, <<"baz">>,
-                                              Since, Fun, Opts, []),
-    {ok, lists:reverse(R)}.
-
-run_count_query(Db, Since, Opts) ->
-    couch_mrview:count_view_changes_since(Db, <<"_design/bar">>, <<"baz">>,
-                                          Since, Opts).

http://git-wip-us.apache.org/repos/asf/couchdb/blob/75150a18/apps/couch_mrview/test/09-index-events.t
----------------------------------------------------------------------
diff --git a/apps/couch_mrview/test/09-index-events.t b/apps/couch_mrview/test/09-index-events.t
deleted file mode 100644
index 6cc1e9c..0000000
--- a/apps/couch_mrview/test/09-index-events.t
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-%%! -pa ./deps/*/ebin -pa ./apps/*/ebin -pa ./test/etap
-
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-%   http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
-main(_) ->
-    etap:plan(5),
-    case (catch test()) of
-        ok ->
-            etap:end_tests();
-        Other ->
-            etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
-            etap:bail(Other)
-    end,
-    timer:sleep(300),
-    ok.
-
-test() ->
-    test_util:start_couch(),
-    {ok, Db} = couch_mrview_test_util:init_db(<<"foo">>, changes),
-    test_info(Db),
-    test_update_event(Db),
-    test_delete_event(Db),
-    test_util:stop_couch(),
-    ok.
-
-test_info(Db) ->
-    {ok, Info} = couch_mrview:get_info(Db, <<"_design/bar">>),
-    etap:is(getval(update_options, Info), [<<"seq_indexed">>],
-            "update options OK"),
-    ok.
-
-test_update_event(Db) ->
-    {ok, Pid} = couch_index_event:start_link(self()),
-    etap:ok(is_pid(Pid), "event handler added"),
-    ok = couch_mrview:refresh(Db, <<"_design/bar">>),
-    Expect = {index_update, {<<"foo">>, <<"_design/bar">>,
-                             couch_mrview_index}},
-    receive
-        Event ->
-            etap:is(Event, Expect, "index update events OK")
-    end,
-    couch_index_event:stop(Pid).
-
-test_delete_event(Db) ->
-    ok = couch_mrview:refresh(Db, <<"_design/bar">>),
-    timer:sleep(300),
-    {ok, Pid} = couch_index_event:start_link(self()),
-    etap:ok(is_pid(Pid), "delete event handler added"),
-
-
-    catch couch_mrview_test_util:delete_db(<<"foo">>),
-    Expect = {index_delete, {<<"foo">>, <<"_design/bar">>,
-                             couch_mrview_index}},
-    receive
-        Event ->
-            etap:is(Event, Expect, "index delete events OK")
-    end,
-    couch_index_event:stop(Pid).
-
-getval(Key, PL) ->
-    {value, {Key, Val}} = lists:keysearch(Key, 1, PL),
-    Val.