diff options
author | benoitc <benoitc@apache.org> | 2014-01-27 17:24:54 +0100 |
---|---|---|
committer | benoitc <benoitc@apache.org> | 2014-01-27 17:24:54 +0100 |
commit | c60c6b606dcde12dfff58405023be951b63f240f (patch) | |
tree | 50aeb59351f99b19633ce36c88b69b4b240ef5ac | |
parent | 6f173d5b394c39542571bf133b5b90d7f5b0651f (diff) | |
download | couchdb-c60c6b606dcde12dfff58405023be951b63f240f.tar.gz |
couch_mrview: add view changes test
test view changes and fix errors.
-rw-r--r-- | apps/couch_mrview/src/couch_mrview_test_util.erl | 31 | ||||
-rw-r--r-- | apps/couch_mrview/src/couch_mrview_updater.erl | 2 | ||||
-rw-r--r-- | apps/couch_mrview/src/couch_mrview_util.erl | 34 | ||||
-rw-r--r-- | apps/couch_mrview/test/08-changes_since.t | 123 |
4 files changed, 168 insertions, 22 deletions
diff --git a/apps/couch_mrview/src/couch_mrview_test_util.erl b/apps/couch_mrview/src/couch_mrview_test_util.erl index adc2675bf..c67f24f1b 100644 --- a/apps/couch_mrview/src/couch_mrview_test_util.erl +++ b/apps/couch_mrview/src/couch_mrview_test_util.erl @@ -41,14 +41,31 @@ save_docs(Db, Docs) -> make_docs(Count) -> - make_docs(Count, []). - -make_docs(Count, Acc) when Count =< 0 -> - Acc; -make_docs(Count, Acc) -> - make_docs(Count-1, [doc(Count) | Acc]). - + [doc(I) || I <- lists:seq(1, Count)]. +ddoc(changes) -> + couch_doc:from_json_obj({[ + {<<"_id">>, <<"_design/bar">>}, + {<<"options">>, {[ + {<<"seq_indexed">>, true} + ]}}, + {<<"views">>, {[ + {<<"baz">>, {[ + {<<"map">>, <<"function(doc) {emit(doc.val, doc.val);}">>} + ]}}, + {<<"bing">>, {[ + {<<"map">>, <<"function(doc) {}">>} + ]}}, + {<<"zing">>, {[ + {<<"map">>, << + "function(doc) {\n" + " if(doc.foo !== undefined)\n" + " emit(doc.foo, 0);\n" + "}" + >>} + ]}} + ]}} + ]}); ddoc(map) -> couch_doc:from_json_obj({[ {<<"_id">>, <<"_design/bar">>}, diff --git a/apps/couch_mrview/src/couch_mrview_updater.erl b/apps/couch_mrview/src/couch_mrview_updater.erl index 58ee9d2b3..be1055c71 100644 --- a/apps/couch_mrview/src/couch_mrview_updater.erl +++ b/apps/couch_mrview/src/couch_mrview_updater.erl @@ -280,7 +280,7 @@ write_kvs(State, UpdateSeq, ViewKVs, DocIdKeys, Log) -> SToRem = couch_util:dict_find(ViewId, SeqsToRemove, []), SToAdd = couch_util:dict_find(ViewId, SeqsToAdd, []), RemSKs = [{Seq, Key} || {Key, Seq, _} <- SToRem], - RemKSs = [{[Seq, Key], DocId} || {Key, Seq, DocId} <- SToRem], + RemKSs = [{[Key, Seq], DocId} || {Key, Seq, DocId} <- SToRem], SKVs1 = SKVs ++ SToAdd, {ok, SBt} = couch_btree:add_remove(View#mrview.seq_btree, SKVs1, RemSKs), diff --git a/apps/couch_mrview/src/couch_mrview_util.erl b/apps/couch_mrview/src/couch_mrview_util.erl index 7c42de8ad..a98f042a7 100644 --- a/apps/couch_mrview/src/couch_mrview_util.erl +++ b/apps/couch_mrview/src/couch_mrview_util.erl @@ -229,13 +229,8 @@ init_state(Db, Fd, State, Header) -> views=Views2 }. -less_json_seqs({SeqA, JsonA}, {SeqB, JsonB}) -> - case couch_ejson_compare:less(SeqA, SeqB) of - 0 -> - couch_ejson_compare:less_json(JsonA, JsonB); - Result -> - Result < 0 - end. +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], @@ -354,12 +349,23 @@ fold_fun(Fun, [KV|Rest], {KVReds, Reds}, Acc) -> {stop, Acc2} end. + fold_changes(Bt, Fun, Acc, Opts) -> WrapperFun = fun(KV, _Reds, Acc2) -> - Fun(changes_expand_dups([KV], []), 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{ @@ -795,15 +801,15 @@ expand_dups([KV | Rest], Acc) -> changes_expand_dups([], Acc) -> lists:reverse(Acc); changes_expand_dups([{{[Key, Seq], DocId}, {dups, Vals}} | Rest], Acc) -> - Expanded = [{{Key, Seq, DocId}, Val} || Val <- Vals], + Expanded = [{{Seq, Key, DocId}, Val} || Val <- Vals], changes_expand_dups(Rest, Expanded ++ Acc); -changes_expand_dups([{{Key, Seq}, {DocId, {dups, Vals}}} | Rest], Acc) -> - Expanded = [{{Key, Seq, DocId}, Val} || Val <- Vals], +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, [{{Key, Seq, DocId}, Val} | Acc]); -changes_expand_dups([{{Key, Seq}, {DocId, Val}} | Rest], Acc) -> - changes_expand_dups(Rest, [{{Key, Seq, DocId}, Val} | 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}) -> []; diff --git a/apps/couch_mrview/test/08-changes_since.t b/apps/couch_mrview/test/08-changes_since.t new file mode 100644 index 000000000..3127cff41 --- /dev/null +++ b/apps/couch_mrview/test/08-changes_since.t @@ -0,0 +1,123 @@ +#!/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(10), + 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_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."). + +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). |