You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2013/06/29 17:18:09 UTC
[28/50] [abbrv] git commit: updated refs/heads/1843-feature-bigcouch
to cba2e81
Reject design docs with compilation errors
If we know the language for a given design doc we'll attempt to compile
the map/reduce functions and reject updates that introduce code that
doesn't compile. We don't yet do the other types of functions because
those errors are more user visible.
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/b474248c
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/b474248c
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/b474248c
Branch: refs/heads/1843-feature-bigcouch
Commit: b474248c6fd7f2bb5bab20225869920d87414ea7
Parents: 0861ab0
Author: Paul J. Davis <pa...@gmail.com>
Authored: Sun Mar 10 16:03:00 2013 -0500
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Wed Mar 20 06:02:54 2013 -0500
----------------------------------------------------------------------
etc/couchdb/default.ini.tpl.in | 3 +++
src/couch/src/couch_db.erl | 15 +++++++++--
src/couch/src/couch_query_servers.erl | 12 +++++++++
src/couch_index/src/couch_index_server.erl | 28 +++++++++++++++++++-
src/couch_mrview/src/couch_mrview.erl | 35 +++++++++++++++++++++++++
5 files changed, 90 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/b474248c/etc/couchdb/default.ini.tpl.in
----------------------------------------------------------------------
diff --git a/etc/couchdb/default.ini.tpl.in b/etc/couchdb/default.ini.tpl.in
index 02341d3..9d9465e 100644
--- a/etc/couchdb/default.ini.tpl.in
+++ b/etc/couchdb/default.ini.tpl.in
@@ -142,6 +142,9 @@ replicator_manager={couch_replicator_manager, start_link, []}
os_daemons={couch_os_daemons, start_link, []}
compaction_daemon={couch_compaction_daemon, start_link, []}
+[indexers]
+couch_mrview = true
+
[httpd_global_handlers]
/ = {couch_httpd_misc_handlers, handle_welcome_req, <<"Welcome">>}
favicon.ico = {couch_httpd_misc_handlers, handle_favicon_req, "%localdatadir%/www"}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/b474248c/src/couch/src/couch_db.erl
----------------------------------------------------------------------
diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl
index 56cb0d2..7734c7c 100644
--- a/src/couch/src/couch_db.erl
+++ b/src/couch/src/couch_db.erl
@@ -502,8 +502,11 @@ group_alike_docs([{Doc,Ref}|Rest], [Bucket|RestBuckets]) ->
group_alike_docs(Rest, [[{Doc,Ref}]|[Bucket|RestBuckets]])
end.
-validate_doc_update(#db{}=Db, #doc{id= <<"_design/",_/binary>>}, _GetDiskDocFun) ->
- catch check_is_admin(Db);
+validate_doc_update(#db{}=Db, #doc{id= <<"_design/",_/binary>>}=Doc, _GetDiskDocFun) ->
+ case catch check_is_admin(Db) of
+ ok -> validate_ddoc(Db#db.name, Doc);
+ Error -> Error
+ end;
validate_doc_update(#db{validate_doc_funs = undefined} = Db, Doc, Fun) ->
ValidationFuns = load_validation_funs(Db),
validate_doc_update(Db#db{validate_doc_funs=ValidationFuns}, Doc, Fun);
@@ -519,6 +522,14 @@ validate_doc_update(Db, Doc, GetDiskDocFun) ->
validate_doc_update_int(Db, Doc, GetDiskDocFun)
end.
+validate_ddoc(DbName, DDoc) ->
+ try
+ couch_index_server:validate(DbName, couch_doc:with_ejson_body(DDoc))
+ catch
+ throw:Error ->
+ Error
+ end.
+
validate_doc_update_int(Db, Doc, GetDiskDocFun) ->
DiskDoc = GetDiskDocFun(),
JsonCtx = couch_util:json_user_ctx(Db),
http://git-wip-us.apache.org/repos/asf/couchdb/blob/b474248c/src/couch/src/couch_query_servers.erl
----------------------------------------------------------------------
diff --git a/src/couch/src/couch_query_servers.erl b/src/couch/src/couch_query_servers.erl
index d919a85..8e4130e 100644
--- a/src/couch/src/couch_query_servers.erl
+++ b/src/couch/src/couch_query_servers.erl
@@ -12,6 +12,7 @@
-module(couch_query_servers).
+-export([try_compile/4]).
-export([start_doc_map/3, map_docs/2, map_docs_raw/2, stop_doc_map/1, raw_to_ejson/1]).
-export([reduce/3, rereduce/3,validate_doc_update/5]).
-export([filter_docs/5]).
@@ -65,6 +66,17 @@
46,65,9,27,108,27,101,27,110,27,103,27,116,27,104,56,9,34,59,84,0,78,84,1,102,
65,9,27,125,56,9,84,1,206,0,0,0,0,0,0,0>>}).
+
+try_compile(Proc, FunctionType, FunctionName, FunctionSource) ->
+ try
+ proc_prompt(Proc, [<<"add_fun">>, FunctionSource]),
+ ok
+ catch {compilation_error, E} ->
+ Fmt = "Compilation of the ~s function in the '~s' view failed: ~s",
+ Msg = io_lib:format(Fmt, [FunctionType, FunctionName, E]),
+ throw({compilation_error, Msg})
+ end.
+
start_doc_map(Lang, Functions, Lib) ->
Proc = get_os_process(Lang),
case Lib of
http://git-wip-us.apache.org/repos/asf/couchdb/blob/b474248c/src/couch_index/src/couch_index_server.erl
----------------------------------------------------------------------
diff --git a/src/couch_index/src/couch_index_server.erl b/src/couch_index/src/couch_index_server.erl
index a106f14..3d8a797 100644
--- a/src/couch_index/src/couch_index_server.erl
+++ b/src/couch_index/src/couch_index_server.erl
@@ -14,7 +14,7 @@
-behaviour(gen_server).
-behaviour(config_listener).
--export([start_link/0, get_index/4, get_index/3, get_index/2]).
+-export([start_link/0, validate/2, get_index/4, get_index/3, get_index/2]).
-export([update_notify/1]).
-export([init/1, terminate/2, code_change/3]).
@@ -35,6 +35,32 @@
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
+
+validate(DbName, DDoc) ->
+ LoadModFun = fun
+ ({ModNameList, "true"}) ->
+ try
+ [list_to_existing_atom(ModNameList)]
+ catch error:badarg ->
+ []
+ end;
+ ({_ModNameList, _Enabled}) ->
+ []
+ end,
+ ValidateFun = fun
+ (ModName, ok) ->
+ try
+ ModName:validate(DbName, DDoc)
+ catch Type:Reason ->
+ {Type, Reason}
+ end;
+ (_ModName, Error) ->
+ Error
+ end,
+ EnabledIndexers = lists:flatmap(LoadModFun, config:get("indexers")),
+ lists:foldl(ValidateFun, ok, EnabledIndexers).
+
+
get_index(Module, <<"shards/", _/binary>>=DbName, DDoc) ->
{Pid, Ref} = spawn_monitor(fun() ->
exit(fabric:open_doc(mem3:dbname(DbName), DDoc, []))
http://git-wip-us.apache.org/repos/asf/couchdb/blob/b474248c/src/couch_mrview/src/couch_mrview.erl
----------------------------------------------------------------------
diff --git a/src/couch_mrview/src/couch_mrview.erl b/src/couch_mrview/src/couch_mrview.erl
index 20ba6d9..29b86d7 100644
--- a/src/couch_mrview/src/couch_mrview.erl
+++ b/src/couch_mrview/src/couch_mrview.erl
@@ -12,6 +12,7 @@
-module(couch_mrview).
+-export([validate/2]).
-export([query_all_docs/2, query_all_docs/4]).
-export([query_view/3, query_view/4, query_view/6]).
-export([get_info/2]).
@@ -40,6 +41,40 @@
}).
+validate(DbName, DDoc) ->
+ GetName = fun
+ (#mrview{map_names = [Name | _]}) -> Name;
+ (#mrview{reduce_funs = [{Name, _} | _]}) -> Name;
+ (_) -> null
+ end,
+ ValidateView = fun(Proc, #mrview{def=MapSrc, reduce_funs=Reds}=View) ->
+ couch_query_servers:try_compile(Proc, map, GetName(View), MapSrc),
+ lists:foreach(fun
+ ({_RedName, <<"_", _/binary>>}) ->
+ ok;
+ ({RedName, RedSrc}) ->
+ couch_query_servers:try_compile(Proc, reduce, RedName, RedSrc)
+ end, Reds)
+ end,
+ {ok, #mrst{language=Lang, views=Views}}
+ = couch_mrview_util:ddoc_to_mrst(DbName, DDoc),
+ try Views =/= [] andalso couch_query_servers:get_os_process(Lang) of
+ false ->
+ ok;
+ Proc ->
+ try
+ lists:foreach(fun(V) -> ValidateView(Proc, V) end, Views)
+ catch Error ->
+ Error
+ after
+ couch_query_servers:ret_os_process(Proc)
+ end
+ catch {unknown_query_language, _Lang} ->
+ %% Allow users to save ddocs written in uknown languages
+ ok
+ end.
+
+
query_all_docs(Db, Args) ->
query_all_docs(Db, Args, fun default_cb/2, []).