diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/couchdb/couch_db.hrl | 1 | ||||
| -rw-r--r-- | src/couchdb/couch_httpd_view.erl | 8 | ||||
| -rw-r--r-- | src/couchdb/couch_view.erl | 25 | ||||
| -rw-r--r-- | src/couchdb/couch_view_group.erl | 7 | ||||
| -rw-r--r-- | src/couchdb/couch_view_updater.erl | 27 | 
5 files changed, 41 insertions, 27 deletions
| diff --git a/src/couchdb/couch_db.hrl b/src/couchdb/couch_db.hrl index eb449ab7..1afea912 100644 --- a/src/couchdb/couch_db.hrl +++ b/src/couchdb/couch_db.hrl @@ -174,6 +174,7 @@      fd=nil,      name,      def_lang, +    design_options=[],      views,      id_btree=nil,      current_seq=0, diff --git a/src/couchdb/couch_httpd_view.erl b/src/couchdb/couch_httpd_view.erl index 0d5c0df4..fc3302d7 100644 --- a/src/couchdb/couch_httpd_view.erl +++ b/src/couchdb/couch_httpd_view.erl @@ -68,15 +68,17 @@ handle_temp_view_req(#httpd{method='POST'}=Req, Db) ->      end,      {Props} = couch_httpd:json_body(Req),      Language = proplists:get_value(<<"language">>, Props, <<"javascript">>), +    {DesignOptions} = proplists:get_value(<<"options">>, Props, {[]}),      MapSrc = proplists:get_value(<<"map">>, Props),      Keys = proplists:get_value(<<"keys">>, Props, nil),      case proplists:get_value(<<"reduce">>, Props, null) of      null -> -        {ok, View} = couch_view:get_temp_map_view(Db, Language, MapSrc), +        {ok, View} = couch_view:get_temp_map_view(Db, Language,  +            DesignOptions, MapSrc),          output_map_view(Req, View, Db, QueryArgs, Keys);      RedSrc -> -        {ok, View} = couch_view:get_temp_reduce_view(Db, Language, MapSrc, -                RedSrc), +        {ok, View} = couch_view:get_temp_reduce_view(Db, Language,  +            DesignOptions, MapSrc, RedSrc),          output_reduce_view(Req, View, QueryArgs, Keys)      end; diff --git a/src/couchdb/couch_view.erl b/src/couchdb/couch_view.erl index 3faec4b9..e790efd3 100644 --- a/src/couchdb/couch_view.erl +++ b/src/couchdb/couch_view.erl @@ -15,7 +15,7 @@  -export([start_link/0,fold/4,fold/5,less_json/2,less_json_keys/2,expand_dups/2,      detuple_kvs/2,init/1,terminate/2,handle_call/3,handle_cast/2,handle_info/2, -    code_change/3,get_reduce_view/4,get_temp_reduce_view/4,get_temp_map_view/3, +    code_change/3,get_reduce_view/4,get_temp_reduce_view/5,get_temp_map_view/4,      get_map_view/4,get_row_count/1,reduce_to_count/1,fold_reduce/7,      extract_map_view/1]). @@ -28,9 +28,9 @@  start_link() ->      gen_server:start_link({local, couch_view}, couch_view, [], []). -get_temp_updater(DbName, Type, MapSrc, RedSrc) -> +get_temp_updater(DbName, Type, DesignOptions, MapSrc, RedSrc) ->      {ok, Pid} = gen_server:call(couch_view, -            {start_temp_updater, DbName, Type, MapSrc, RedSrc}), +            {start_temp_updater, DbName, Type, DesignOptions, MapSrc, RedSrc}),      Pid.  get_group_server(DbName, GroupId) -> @@ -51,17 +51,17 @@ get_group(Db, GroupId, Stale) ->              MinUpdateSeq). -get_temp_group(Db, Type, MapSrc, RedSrc) -> +get_temp_group(Db, Type, DesignOptions, MapSrc, RedSrc) ->      couch_view_group:request_group( -            get_temp_updater(couch_db:name(Db), Type, MapSrc, RedSrc), +            get_temp_updater(couch_db:name(Db), Type, DesignOptions, MapSrc, RedSrc),              couch_db:get_update_seq(Db)).  get_row_count(#view{btree=Bt}) ->      {ok, {Count, _Reds}} = couch_btree:full_reduce(Bt),      {ok, Count}. -get_temp_reduce_view(Db, Type, MapSrc, RedSrc) -> -    {ok, #group{views=[View]}} = get_temp_group(Db, Type, MapSrc, RedSrc), +get_temp_reduce_view(Db, Type, DesignOptions, MapSrc, RedSrc) -> +    {ok, #group{views=[View]}} = get_temp_group(Db, Type, DesignOptions, MapSrc, RedSrc),      {ok, {temp_reduce, View}}. @@ -136,8 +136,8 @@ get_key_pos(Key, [_|Rest], N) ->      get_key_pos(Key, Rest, N+1). -get_temp_map_view(Db, Type, Src) -> -    {ok, #group{views=[View]}} = get_temp_group(Db, Type, Src, []), +get_temp_map_view(Db, Type, DesignOptions, Src) -> +    {ok, #group{views=[View]}} = get_temp_group(Db, Type, DesignOptions, Src, []),      {ok, View}.  get_map_view(Db, GroupId, Name, Stale) -> @@ -220,8 +220,9 @@ terminate(_Reason,_State) ->      ok. -handle_call({start_temp_updater, DbName, Lang, MapSrc, RedSrc}, _From, #server{root_dir=Root}=Server) ->     -    <<SigInt:128/integer>> = erlang:md5(term_to_binary({Lang, MapSrc, RedSrc})), +handle_call({start_temp_updater, DbName, Lang, DesignOptions, MapSrc, RedSrc}, +                                                _From, #server{root_dir=Root}=Server) -> +    <<SigInt:128/integer>> = erlang:md5(term_to_binary({Lang, DesignOptions, MapSrc, RedSrc})),      Name = lists:flatten(io_lib:format("_temp_~.36B",[SigInt])),      Pid =       case ets:lookup(group_servers_by_name, {DbName, Name}) of @@ -235,7 +236,7 @@ handle_call({start_temp_updater, DbName, Lang, MapSrc, RedSrc}, _From, #server{r              ok          end,          ?LOG_DEBUG("Spawning new temp update process for db ~s.", [DbName]), -        {ok, NewPid} = couch_view_group:start_link({slow_view, DbName, Fd, Lang, MapSrc, RedSrc}), +        {ok, NewPid} = couch_view_group:start_link({slow_view, DbName, Fd, Lang, DesignOptions, MapSrc, RedSrc}),          true = ets:insert(couch_temp_group_fd_by_db, {DbName, Fd, Count + 1}),          add_to_ets(NewPid, DbName, Name),          NewPid; diff --git a/src/couchdb/couch_view_group.erl b/src/couchdb/couch_view_group.erl index 6d193516..4e7d7767 100644 --- a/src/couchdb/couch_view_group.erl +++ b/src/couchdb/couch_view_group.erl @@ -262,7 +262,7 @@ prepare_group({view, RootDir, DbName, GroupId}, ForceReset)->          catch delete_index_file(RootDir, DbName, GroupId),          Error      end; -prepare_group({slow_view, DbName, Fd, Lang, MapSrc, RedSrc}, _ForceReset) -> +prepare_group({slow_view, DbName, Fd, Lang, DesignOptions, MapSrc, RedSrc}, _ForceReset) ->      case couch_db:open(DbName, []) of      {ok, Db} ->          View = #view{map_names=[<<"_temp">>], @@ -271,7 +271,7 @@ prepare_group({slow_view, DbName, Fd, Lang, MapSrc, RedSrc}, _ForceReset) ->              def=MapSrc,              reduce_funs= if RedSrc==[] -> []; true -> [{<<"_temp">>, RedSrc}] end},          {ok, init_group(Db, Fd, #group{type=slow_view, name= <<"_temp">>, db=Db, -                views=[View], def_lang=Lang}, nil)}; +            views=[View], def_lang=Lang, design_options=DesignOptions}, nil)};      Error ->          Error      end. @@ -311,6 +311,7 @@ open_db_group(DbName, GroupId) ->  % maybe move to another module  design_doc_to_view_group(#doc{id=Id,body={Fields}}) ->      Language = proplists:get_value(<<"language">>, Fields, <<"javascript">>), +    {DesignOptions} = proplists:get_value(<<"options">>, Fields, {[]}),      {RawViews} = proplists:get_value(<<"views">>, Fields, {[]}),      % add the views to a dictionary object, with the map source as the key @@ -338,7 +339,7 @@ design_doc_to_view_group(#doc{id=Id,body={Fields}}) ->              {View#view{id_num=N},N+1}          end, 0, dict:to_list(DictBySrc)), -    Group = #group{name=Id, views=Views, def_lang=Language}, +    Group = #group{name=Id, views=Views, def_lang=Language, design_options=DesignOptions},      Group#group{sig=erlang:md5(term_to_binary(Group))}.  reset_group(#group{views=Views}=Group) -> diff --git a/src/couchdb/couch_view_updater.erl b/src/couchdb/couch_view_updater.erl index b6ae860f..956ac3f1 100644 --- a/src/couchdb/couch_view_updater.erl +++ b/src/couchdb/couch_view_updater.erl @@ -90,43 +90,52 @@ purge_index(#group{db=Db, views=Views, id_btree=IdBtree}=Group) ->              views=Views2,              purge_seq=couch_db:get_purge_seq(Db)}. -process_doc(Db, DocInfo, {Docs, #group{sig=Sig,name=GroupId}=Group, ViewKVs, +process_doc(Db, DocInfo, {Docs, #group{sig=Sig,name=GroupId,design_options=DesignOptions}=Group, ViewKVs,          DocIdViewIdKeys}) ->      % This fun computes once for each document              #doc_info{id=DocId, deleted=Deleted} = DocInfo, -    case DocId of -    GroupId -> +    IncludeDesign = proplists:get_value(<<"include_design">>,  +        DesignOptions, false), +    case {IncludeDesign, DocId} of +    {_, GroupId} ->          % uh oh. this is the design doc with our definitions. See if          % anything in the definition changed. -        case couch_db:open_doc(Db, DocInfo) of +        case couch_db:open_doc(Db, DocInfo, [conflicts, deleted_conflicts]) of          {ok, Doc} ->              case couch_view_group:design_doc_to_view_group(Doc) of              #group{sig=Sig} ->                  % The same md5 signature, keep on computing -                {Docs, Group, ViewKVs, DocIdViewIdKeys}; +                case IncludeDesign of +                true -> +                    {[Doc | Docs], Group, ViewKVs, DocIdViewIdKeys}; +                _ -> +                    {Docs, Group, ViewKVs, DocIdViewIdKeys} +                end;              _ ->                  exit(reset)              end;          {not_found, deleted} ->              exit(reset)          end; -    <<?DESIGN_DOC_PREFIX, _/binary>> -> % we skip design docs +    {false, <<?DESIGN_DOC_PREFIX, _/binary>>} -> % we skip design docs          {Docs, Group, ViewKVs, DocIdViewIdKeys};      _ ->          {Docs2, DocIdViewIdKeys2} =          if Deleted ->              {Docs, [{DocId, []} | DocIdViewIdKeys]};          true -> -            {ok, Doc} = couch_db:open_doc(Db, DocInfo, [conflicts, deleted_conflicts]), +            {ok, Doc} = couch_db:open_doc(Db, DocInfo,  +                [conflicts, deleted_conflicts]),              {[Doc | Docs], DocIdViewIdKeys}          end,          case couch_util:should_flush() of          true ->              {Group1, Results} = view_compute(Group, Docs2), -            {ViewKVs3, DocIdViewIdKeys3} = view_insert_query_results(Docs2, Results, ViewKVs, DocIdViewIdKeys2), +            {ViewKVs3, DocIdViewIdKeys3} = view_insert_query_results(Docs2,  +                Results, ViewKVs, DocIdViewIdKeys2),              {ok, Group2} = write_changes(Group1, ViewKVs3, DocIdViewIdKeys3, -                    DocInfo#doc_info.update_seq), +                DocInfo#doc_info.update_seq),              garbage_collect(),              ViewEmptyKeyValues = [{View, []} || View <- Group2#group.views],              {[], Group2, ViewEmptyKeyValues, []}; | 
