From commits-return-1785-apmail-couchdb-commits-archive=couchdb.apache.org@couchdb.apache.org Sun Feb 01 22:21:34 2009 Return-Path: Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: (qmail 40755 invoked from network); 1 Feb 2009 22:21:34 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 1 Feb 2009 22:21:34 -0000 Received: (qmail 1994 invoked by uid 500); 1 Feb 2009 22:21:34 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 1907 invoked by uid 500); 1 Feb 2009 22:21:34 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 1898 invoked by uid 99); 1 Feb 2009 22:21:33 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 01 Feb 2009 14:21:33 -0800 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 01 Feb 2009 22:21:31 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id D12C92388A2E; Sun, 1 Feb 2009 22:21:09 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r739866 - in /couchdb/trunk: share/www/script/couch.js share/www/script/couch_tests.js src/couchdb/couch_db.hrl src/couchdb/couch_httpd_view.erl src/couchdb/couch_view.erl src/couchdb/couch_view_group.erl src/couchdb/couch_view_updater.erl Date: Sun, 01 Feb 2009 22:21:09 -0000 To: commits@couchdb.apache.org From: jchris@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090201222109.D12C92388A2E@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jchris Date: Sun Feb 1 22:21:09 2009 New Revision: 739866 URL: http://svn.apache.org/viewvc?rev=739866&view=rev Log: Added options member to design docs. Currently the only option is include_designs (views can now run over design docs as well if they need to), the default is false, which is the current behavior. Thanks davisp for the original patch. Closes COUCHDB-156 Modified: couchdb/trunk/share/www/script/couch.js couchdb/trunk/share/www/script/couch_tests.js couchdb/trunk/src/couchdb/couch_db.hrl couchdb/trunk/src/couchdb/couch_httpd_view.erl couchdb/trunk/src/couchdb/couch_view.erl couchdb/trunk/src/couchdb/couch_view_group.erl couchdb/trunk/src/couchdb/couch_view_updater.erl Modified: couchdb/trunk/share/www/script/couch.js URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/couch.js?rev=739866&r1=739865&r2=739866&view=diff ============================================================================== --- couchdb/trunk/share/www/script/couch.js [utf-8] (original) +++ couchdb/trunk/share/www/script/couch.js [utf-8] Sun Feb 1 22:21:09 2009 @@ -129,6 +129,10 @@ reduceFun = reduceFun.toSource ? reduceFun.toSource() : "(" + reduceFun.toString() + ")"; body.reduce = reduceFun; } + if (options && options.options != undefined) { + body.options = options.options; + delete options.options; + } this.last_req = this.request("POST", this.uri + "_temp_view" + encodeOptions(options), { headers: {"Content-Type": "application/json"}, body: JSON.stringify(body) Modified: couchdb/trunk/share/www/script/couch_tests.js URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/couch_tests.js?rev=739866&r1=739865&r2=739866&view=diff ============================================================================== --- couchdb/trunk/share/www/script/couch_tests.js [utf-8] (original) +++ couchdb/trunk/share/www/script/couch_tests.js [utf-8] Sun Feb 1 22:21:09 2009 @@ -773,6 +773,58 @@ } }, + design_options: function(debug) { + var db = new CouchDB("test_suite_db"); + db.deleteDb(); + db.createDb(); + if (debug) debugger; + + //// test the includes_design option + var map = "function (doc) {emit(null, doc._id);}"; + + // we need a design doc even to test temp views with it + var designDoc = { + _id:"_design/fu", + language: "javascript", + options: { + include_design: true + }, + views: { + data: {"map": map} + } + }; + T(db.save(designDoc).ok); + + // should work for temp views + var rows = db.query(map, null, {options:{include_design: true}}).rows; + T(rows.length == 1); + T(rows[0].value == "_design/fu"); + + rows = db.query(map).rows; + T(rows.length == 0); + + // when true, should include design docs in views + rows = db.view("fu/data").rows; + T(rows.length == 1); + T(rows[0].value == "_design/fu"); + + // when false, should not + designDoc.options.include_design = false; + delete designDoc._rev; + designDoc._id = "_design/bingo"; + T(db.save(designDoc).ok); + rows = db.view("bingo/data").rows; + T(rows.length == 0); + + // should default to false + delete designDoc.options; + delete designDoc._rev; + designDoc._id = "_design/bango"; + T(db.save(designDoc).ok); + rows = db.view("bango/data").rows; + T(rows.length == 0); + }, + multiple_rows: function(debug) { var db = new CouchDB("test_suite_db"); db.deleteDb(); Modified: couchdb/trunk/src/couchdb/couch_db.hrl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_db.hrl?rev=739866&r1=739865&r2=739866&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_db.hrl (original) +++ couchdb/trunk/src/couchdb/couch_db.hrl Sun Feb 1 22:21:09 2009 @@ -174,6 +174,7 @@ fd=nil, name, def_lang, + design_options=[], views, id_btree=nil, current_seq=0, Modified: couchdb/trunk/src/couchdb/couch_httpd_view.erl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_view.erl?rev=739866&r1=739865&r2=739866&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_httpd_view.erl (original) +++ couchdb/trunk/src/couchdb/couch_httpd_view.erl Sun Feb 1 22:21:09 2009 @@ -68,15 +68,17 @@ 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; Modified: couchdb/trunk/src/couchdb/couch_view.erl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_view.erl?rev=739866&r1=739865&r2=739866&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_view.erl (original) +++ couchdb/trunk/src/couchdb/couch_view.erl Sun Feb 1 22:21:09 2009 @@ -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 @@ 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+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 @@ ok. -handle_call({start_temp_updater, DbName, Lang, MapSrc, RedSrc}, _From, #server{root_dir=Root}=Server) -> - <> = erlang:md5(term_to_binary({Lang, MapSrc, RedSrc})), +handle_call({start_temp_updater, DbName, Lang, DesignOptions, MapSrc, RedSrc}, + _From, #server{root_dir=Root}=Server) -> + <> = 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 @@ 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; Modified: couchdb/trunk/src/couchdb/couch_view_group.erl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_view_group.erl?rev=739866&r1=739865&r2=739866&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_view_group.erl (original) +++ couchdb/trunk/src/couchdb/couch_view_group.erl Sun Feb 1 22:21:09 2009 @@ -262,7 +262,7 @@ 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 @@ 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 @@ % 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 @@ {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) -> Modified: couchdb/trunk/src/couchdb/couch_view_updater.erl URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_view_updater.erl?rev=739866&r1=739865&r2=739866&view=diff ============================================================================== --- couchdb/trunk/src/couchdb/couch_view_updater.erl (original) +++ couchdb/trunk/src/couchdb/couch_view_updater.erl Sun Feb 1 22:21:09 2009 @@ -90,43 +90,52 @@ 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; - <> -> % we skip design docs + {false, <>} -> % 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, []};