summaryrefslogtreecommitdiff
path: root/src/couch_eval/src/couch_eval.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couch_eval/src/couch_eval.erl')
-rw-r--r--src/couch_eval/src/couch_eval.erl55
1 files changed, 53 insertions, 2 deletions
diff --git a/src/couch_eval/src/couch_eval.erl b/src/couch_eval/src/couch_eval.erl
index 3541a5b94..f87ba97b9 100644
--- a/src/couch_eval/src/couch_eval.erl
+++ b/src/couch_eval/src/couch_eval.erl
@@ -17,7 +17,9 @@
-export([
acquire_map_context/6,
release_map_context/1,
- map_docs/2
+ map_docs/2,
+ with_context/2,
+ try_compile/4
]).
@@ -35,6 +37,10 @@
-type result() :: {doc_id(), [[{any(), any()}]]}.
-type api_mod() :: atom().
-type context() :: {api_mod(), any()}.
+-type function_type() :: binary() | atom().
+-type function_name() :: binary().
+-type function_src() :: binary().
+-type error(_Error) :: no_return().
-type context_opts() :: #{
db_name := db_name(),
@@ -46,10 +52,17 @@
api_mod => api_mod()
}.
+-type with_context_opts() :: #{
+ language := language()
+}.
+
-callback acquire_map_context(context_opts()) -> {ok, any()} | {error, any()}.
-callback release_map_context(context()) -> ok | {error, any()}.
-callback map_docs(context(), [doc()]) -> {ok, [result()]} | {error, any()}.
+-callback acquire_context() -> {ok, any()} | {error, any()}.
+-callback release_context(context()) -> ok | {error, any()}.
+-callback try_compile(context(), function_type(), function_name(), function_src()) -> ok.
-spec acquire_map_context(
@@ -59,7 +72,10 @@
sig(),
lib(),
map_funs()
- ) -> {ok, context()} | {error, any()}.
+ ) ->
+ {ok, context()}
+ | error({invalid_eval_api_mod, Language :: binary()})
+ | error({unknown_eval_api_language, Language :: binary()}).
acquire_map_context(DbName, DDocId, Language, Sig, Lib, MapFuns) ->
ApiMod = get_api_mod(Language),
CtxOpts = #{
@@ -87,6 +103,41 @@ map_docs({ApiMod, Ctx}, Docs) ->
ApiMod:map_docs(Ctx, Docs).
+-spec with_context(with_context_opts(), function()) ->
+ any()
+ | error({invalid_eval_api_mod, Language :: binary()})
+ | error({unknown_eval_api_language, Language :: binary()}).
+with_context(#{language := Language}, Fun) ->
+ {ok, Ctx} = acquire_context(Language),
+ try
+ Fun(Ctx)
+ after
+ release_context(Ctx)
+ end.
+
+
+-spec try_compile(context(), function_type(), function_name(), function_src()) -> ok.
+try_compile({_ApiMod, _Ctx}, reduce, <<_/binary>>, disabled) ->
+ % Reduce functions may be disabled. Accept that as a valid configuration.
+ ok;
+
+try_compile({ApiMod, Ctx}, FuncType, FuncName, FuncSrc) ->
+ ApiMod:try_compile(Ctx, FuncType, FuncName, FuncSrc).
+
+
+acquire_context(Language) ->
+ ApiMod = get_api_mod(Language),
+ {ok, Ctx} = ApiMod:acquire_context(),
+ {ok, {ApiMod, Ctx}}.
+
+
+release_context(nil) ->
+ ok;
+
+release_context({ApiMod, Ctx}) ->
+ ApiMod:release_context(Ctx).
+
+
get_api_mod(Language) when is_binary(Language) ->
try
LangStr = binary_to_list(Language),