Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

CommonJS support in map functions

git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@1001895 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
commit 7665e449cdfff1e660ed2bbac3de4507cb063a18 1 parent 6c6db01
Chris Anderson jchris authored
1  share/server/loop.js
View
@@ -100,6 +100,7 @@ var Loop = function() {
// "view" : Views.handler,
"reset" : State.reset,
"add_fun" : State.addFun,
+ "add_lib" : State.addLib,
"map_doc" : Views.mapDoc,
"reduce" : Views.reduce,
"rereduce" : Views.rereduce
7 share/server/state.js
View
@@ -14,6 +14,7 @@ var State = {
reset : function(config) {
// clear the globals and run gc
State.funs = [];
+ State.lib = null;
State.query_config = config || {};
init_sandbox();
gc();
@@ -21,7 +22,11 @@ var State = {
},
addFun : function(newFun) {
// Compile to a function and add it to funs array
- State.funs.push(Couch.compileFunction(newFun));
+ State.funs.push(Couch.compileFunction(newFun, {views : {lib : State.lib}}));
+ print("true");
+ },
+ addLib : function(lib) {
+ State.lib = lib;
print("true");
}
}
19 share/www/script/test/design_docs.js
View
@@ -54,7 +54,18 @@ function() {
summate2: {map:"function (doc) {emit(doc.integer, doc.integer)};",
reduce:"function (keys, values) { return sum(values); };"},
huge_src_and_results: {map: "function(doc) { if (doc._id == \"1\") { emit(\"" + makebigstring(16) + "\", null) }}",
- reduce:"function (keys, values) { return \"" + makebigstring(16) + "\"; };"}
+ reduce:"function (keys, values) { return \"" + makebigstring(16) + "\"; };"},
+ lib : {
+ baz : "exports.baz = 'bam';",
+ foo : {
+ foo : "exports.foo = 'bar';",
+ boom : "exports.boom = 'ok';",
+ zoom : "exports.zoom = 'yeah';"
+ }
+ },
+ commonjs : {
+ map : "function(doc) { emit(null, require('views/lib/foo/boom').boom)}"
+ }
},
shows: {
simple: "function() {return 'ok'};",
@@ -99,10 +110,14 @@ function() {
var vinfo = dinfo.view_index;
TEquals(51, vinfo.disk_size);
TEquals(false, vinfo.compact_running);
- TEquals("3f88e53b303e2342e49a66c538c30679", vinfo.signature);
+ TEquals("dc3264b45b74cc6d94666e3043e07154", vinfo.signature, 'ddoc sig');
db.bulkSave(makeDocs(1, numDocs + 1));
+ // test commonjs in map functions
+ resp = db.view("test/commonjs", {limit:1});
+ T(resp.rows[0].value == 'ok');
+
// test that the _all_docs view returns correctly with keys
var results = db.allDocs({startkey:"_design", endkey:"_design0"});
T(results.rows.length == 1);
1  src/couchdb/couch_db.hrl
View
@@ -231,6 +231,7 @@
def_lang,
design_options=[],
views,
+ lib,
id_btree=nil,
current_seq=0,
purge_seq=0,
9 src/couchdb/couch_query_servers.erl
View
@@ -16,7 +16,7 @@
-export([start_link/0]).
-export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2,code_change/3]).
--export([start_doc_map/2, map_docs/2, stop_doc_map/1]).
+-export([start_doc_map/3, map_docs/2, stop_doc_map/1]).
-export([reduce/3, rereduce/3,validate_doc_update/5]).
-export([filter_docs/5]).
@@ -47,8 +47,13 @@
start_link() ->
gen_server:start_link({local, couch_query_servers}, couch_query_servers, [], []).
-start_doc_map(Lang, Functions) ->
+start_doc_map(Lang, Functions, Lib) ->
Proc = get_os_process(Lang),
+ case Lib of
+ {[]} -> ok;
+ Lib ->
+ true = proc_prompt(Proc, [<<"add_lib">>, Lib])
+ end,
lists:foreach(fun(FunctionSource) ->
true = proc_prompt(Proc, [<<"add_fun">>, FunctionSource])
end, Functions),
58 src/couchdb/couch_view_group.erl
View
@@ -446,7 +446,7 @@ open_temp_group(DbName, Language, DesignOptions, MapSrc, RedSrc) ->
reduce_funs= if RedSrc==[] -> []; true -> [{<<"_temp">>, RedSrc}] end,
options=DesignOptions},
- {ok, Db, set_view_sig(#group{name = <<"_temp">>, db=Db, views=[View],
+ {ok, Db, set_view_sig(#group{name = <<"_temp">>,lib={[]}, db=Db, views=[View],
def_lang=Language, design_options=DesignOptions})};
Error ->
Error
@@ -454,9 +454,26 @@ open_temp_group(DbName, Language, DesignOptions, MapSrc, RedSrc) ->
set_view_sig(#group{
views=Views,
+ lib={[]},
def_lang=Language,
design_options=DesignOptions}=G) ->
- G#group{sig=couch_util:md5(term_to_binary({Views, Language, DesignOptions}))}.
+ G#group{sig=couch_util:md5(term_to_binary({Views, Language, DesignOptions}))};
+set_view_sig(#group{
+ views=Views,
+ lib=Lib,
+ def_lang=Language,
+ design_options=DesignOptions}=G) ->
+ G#group{sig=couch_util:md5(term_to_binary({Views, Language, DesignOptions, sort_lib(Lib)}))}.
+
+sort_lib({Lib}) ->
+ sort_lib(Lib, []).
+sort_lib([], LAcc) ->
+ lists:keysort(1, LAcc);
+sort_lib([{LName, {LObj}}|Rest], LAcc) ->
+ LSorted = sort_lib(LObj, []), % descend into nested object
+ sort_lib(Rest, [{LName, LSorted}|LAcc]);
+sort_lib([{LName, LCode}|Rest], LAcc) ->
+ sort_lib(Rest, [{LName, LCode}|LAcc]).
open_db_group(DbName, GroupId) ->
case couch_db:open_int(DbName, []) of
@@ -505,33 +522,36 @@ design_doc_to_view_group(#doc{id=Id,body={Fields}}) ->
Language = ?getv(<<"language">>, Fields, <<"javascript">>),
{DesignOptions} = ?getv(<<"options">>, Fields, {[]}),
{RawViews} = ?getv(<<"views">>, Fields, {[]}),
+ Lib = ?getv(<<"lib">>, RawViews, {[]}),
% add the views to a dictionary object, with the map source as the key
DictBySrc =
lists:foldl(
fun({Name, {MRFuns}}, DictBySrcAcc) ->
- MapSrc = ?getv(<<"map">>, MRFuns),
- RedSrc = ?getv(<<"reduce">>, MRFuns, null),
- {ViewOptions} = ?getv(<<"options">>, MRFuns, {[]}),
- View =
- case dict:find({MapSrc, ViewOptions}, DictBySrcAcc) of
- {ok, View0} -> View0;
- error -> #view{def=MapSrc, options=ViewOptions} % create new view object
- end,
- View2 =
- if RedSrc == null ->
- View#view{map_names=[Name|View#view.map_names]};
- true ->
- View#view{reduce_funs=[{Name,RedSrc}|View#view.reduce_funs]}
- end,
- dict:store({MapSrc, ViewOptions}, View2, DictBySrcAcc)
+ case ?getv(<<"map">>, MRFuns) of
+ undefined -> DictBySrcAcc;
+ MapSrc ->
+ RedSrc = ?getv(<<"reduce">>, MRFuns, null),
+ {ViewOptions} = ?getv(<<"options">>, MRFuns, {[]}),
+ View =
+ case dict:find({MapSrc, ViewOptions}, DictBySrcAcc) of
+ {ok, View0} -> View0;
+ error -> #view{def=MapSrc, options=ViewOptions} % create new view object
+ end,
+ View2 =
+ if RedSrc == null ->
+ View#view{map_names=[Name|View#view.map_names]};
+ true ->
+ View#view{reduce_funs=[{Name,RedSrc}|View#view.reduce_funs]}
+ end,
+ dict:store({MapSrc, ViewOptions}, View2, DictBySrcAcc)
+ end
end, dict:new(), RawViews),
% number the views
{Views, _N} = lists:mapfoldl(
fun({_Src, View}, N) ->
{View#view{id_num=N},N+1}
end, 0, lists:sort(dict:to_list(DictBySrc))),
-
- set_view_sig(#group{name=Id, views=Views, def_lang=Language, design_options=DesignOptions}).
+ set_view_sig(#group{name=Id, lib=Lib, views=Views, def_lang=Language, design_options=DesignOptions}).
reset_group(#group{views=Views}=Group) ->
Views2 = [View#view{btree=nil} || View <- Views],
4 src/couchdb/couch_view_updater.erl
View
@@ -203,12 +203,12 @@ view_insert_doc_query_results(#doc{id=DocId}=Doc, [ResultKVs|RestResults], [{Vie
view_compute(Group, []) ->
{Group, []};
-view_compute(#group{def_lang=DefLang, query_server=QueryServerIn}=Group, Docs) ->
+view_compute(#group{def_lang=DefLang, lib=Lib, query_server=QueryServerIn}=Group, Docs) ->
{ok, QueryServer} =
case QueryServerIn of
nil -> % doc map not started
Definitions = [View#view.def || View <- Group#group.views],
- couch_query_servers:start_doc_map(DefLang, Definitions);
+ couch_query_servers:start_doc_map(DefLang, Definitions, Lib);
_ ->
{ok, QueryServerIn}
end,
Please sign in to comment.
Something went wrong with that request. Please try again.