You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by jc...@apache.org on 2009/02/01 23:21:09 UTC
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
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) ->
- <<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 @@
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;
- <<?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, []};