You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2021/04/06 08:56:45 UTC

[couchdb] branch main updated (f6f81be -> 8843083)

This is an automated email from the ASF dual-hosted git repository.

garren pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git.


    from f6f81be  Fix collation issue for older versions of libicu library
     new 8736b98  Validate ddoc uses couch_eval
     new 8843083  remove couch_index_server:validate

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/couch/src/couch_db.erl                         |  2 +-
 src/couch/test/exunit/fabric_test.exs              |  2 +-
 src/couch_eval/src/couch_eval.erl                  | 51 +++++++++++++++++++++-
 src/couch_index/src/couch_index_server.erl         | 21 +--------
 src/couch_js/src/couch_js.erl                      | 17 +++++++-
 src/couch_mrview/src/couch_mrview.erl              | 23 +++-------
 .../test/eunit/couch_replicator_test_helper.erl    |  2 +-
 src/fabric/src/fabric2_db.erl                      |  2 +-
 src/fabric/test/fabric2_doc_crud_tests.erl         |  2 +-
 src/mango/src/mango_eval.erl                       | 17 +++++++-
 test/elixir/lib/setup/common.ex                    |  4 +-
 11 files changed, 96 insertions(+), 47 deletions(-)

[couchdb] 01/02: Validate ddoc uses couch_eval

Posted by ga...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

garren pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 8736b9846f1b6d388977a4c1a34033781c26a883
Author: garren smith <ga...@gmail.com>
AuthorDate: Tue Mar 30 14:49:09 2021 +0200

    Validate ddoc uses couch_eval
    
    Change the validate ddoc check to use couch_eval.
    Also add in some extra functions in couch_eval so that the try_compile
    will work.
---
 src/couch/test/exunit/fabric_test.exs              |  2 +-
 src/couch_eval/src/couch_eval.erl                  | 51 +++++++++++++++++++++-
 src/couch_js/src/couch_js.erl                      | 17 +++++++-
 src/couch_mrview/src/couch_mrview.erl              | 23 +++-------
 .../test/eunit/couch_replicator_test_helper.erl    |  2 +-
 src/fabric/src/fabric2_db.erl                      |  2 +-
 src/fabric/test/fabric2_doc_crud_tests.erl         |  2 +-
 src/mango/src/mango_eval.erl                       | 17 +++++++-
 test/elixir/lib/setup/common.ex                    |  4 +-
 9 files changed, 94 insertions(+), 26 deletions(-)

diff --git a/src/couch/test/exunit/fabric_test.exs b/src/couch/test/exunit/fabric_test.exs
index bdb84e9..4cbd26b 100644
--- a/src/couch/test/exunit/fabric_test.exs
+++ b/src/couch/test/exunit/fabric_test.exs
@@ -15,7 +15,7 @@ defmodule Couch.Test.Fabric do
   def with_db(context, setup) do
     setup =
       setup
-      |> Setup.Common.with_db()
+      |> Setup.Common.with_db([:couch_js])
       |> Setup.run()
 
     context =
diff --git a/src/couch_eval/src/couch_eval.erl b/src/couch_eval/src/couch_eval.erl
index 3541a5b..a6e5965 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().
+-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,37 @@ 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}, 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),
diff --git a/src/couch_js/src/couch_js.erl b/src/couch_js/src/couch_js.erl
index 1bc0f19..a9c974e 100644
--- a/src/couch_js/src/couch_js.erl
+++ b/src/couch_js/src/couch_js.erl
@@ -18,7 +18,10 @@
 -export([
     acquire_map_context/1,
     release_map_context/1,
-    map_docs/2
+    map_docs/2,
+    acquire_context/0,
+    release_context/1,
+    try_compile/4
 ]).
 
 
@@ -49,3 +52,15 @@ map_docs(Proc, Docs) ->
         end, Results),
         {Doc#doc.id, Tupled}
     end, Docs)}.
+
+acquire_context() ->
+    Ctx = couch_query_servers:get_os_process(?JS),
+    {ok, Ctx}.
+
+
+release_context(Proc) ->
+    couch_query_servers:ret_os_process(Proc).
+
+
+try_compile(Proc, FunctionType, FunName, FunSrc) ->
+    couch_query_servers:try_compile(Proc, FunctionType, FunName, FunSrc).
diff --git a/src/couch_mrview/src/couch_mrview.erl b/src/couch_mrview/src/couch_mrview.erl
index 880dfa7..32f823d 100644
--- a/src/couch_mrview/src/couch_mrview.erl
+++ b/src/couch_mrview/src/couch_mrview.erl
@@ -188,8 +188,8 @@ validate(DbName, _IsDbPartitioned,  DDoc) ->
         (#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),
+    ValidateView = fun(Ctx, #mrview{def=MapSrc, reduce_funs=Reds}=View) ->
+        couch_eval:try_compile(Ctx, map, GetName(View), MapSrc),
         lists:foreach(fun
             ({_RedName, <<"_sum", _/binary>>}) ->
                 ok;
@@ -203,7 +203,7 @@ validate(DbName, _IsDbPartitioned,  DDoc) ->
                 Msg = ["`", Bad, "` is not a supported reduce function."],
                 throw({invalid_design_doc, Msg});
             ({RedName, RedSrc}) ->
-                couch_query_servers:try_compile(Proc, reduce, RedName, RedSrc)
+                couch_eval:try_compile(Ctx, reduce, RedName, RedSrc)
         end, Reds)
     end,
     {ok, #mrst{
@@ -211,19 +211,10 @@ validate(DbName, _IsDbPartitioned,  DDoc) ->
         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)
-            after
-                couch_query_servers:ret_os_process(Proc)
-            end
-    catch {unknown_query_language, _Lang} ->
-    %% Allow users to save ddocs written in unknown languages
-        ok
-    end.
+    Views =/= [] andalso couch_eval:with_context(#{language => Lang}, fun (Ctx) ->
+        lists:foreach(fun(V) -> ValidateView(Ctx, V) end, Views)
+    end),
+    ok.
 
 
 query_all_docs(Db, Args) ->
diff --git a/src/couch_replicator/test/eunit/couch_replicator_test_helper.erl b/src/couch_replicator/test/eunit/couch_replicator_test_helper.erl
index 2ac447e..39717dd 100644
--- a/src/couch_replicator/test/eunit/couch_replicator_test_helper.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_test_helper.erl
@@ -56,7 +56,7 @@
 
 
 start_couch() ->
-    Ctx = test_util:start_couch([fabric, chttpd, couch_replicator]),
+    Ctx = test_util:start_couch([fabric, chttpd, couch_replicator, couch_js]),
     Hashed = couch_passwords:hash_admin_password(?PASSWORD),
     ok = config:set("admins", ?USERNAME, ?b2l(Hashed), _Persist = false),
     Ctx.
diff --git a/src/fabric/src/fabric2_db.erl b/src/fabric/src/fabric2_db.erl
index 6d8bb72..4e0a9fd 100644
--- a/src/fabric/src/fabric2_db.erl
+++ b/src/fabric/src/fabric2_db.erl
@@ -2154,7 +2154,7 @@ validate_doc_update(Db, Doc, PrevDoc) ->
 
 validate_ddoc(Db, DDoc) ->
     try
-        ok = couch_index_server:validate(Db, couch_doc:with_ejson_body(DDoc))
+        ok = couch_mrview:validate(Db, couch_doc:with_ejson_body(DDoc))
     catch
         throw:{invalid_design_doc, Reason} ->
             throw({bad_request, invalid_design_doc, Reason});
diff --git a/src/fabric/test/fabric2_doc_crud_tests.erl b/src/fabric/test/fabric2_doc_crud_tests.erl
index 7a24b7d..bc78887 100644
--- a/src/fabric/test/fabric2_doc_crud_tests.erl
+++ b/src/fabric/test/fabric2_doc_crud_tests.erl
@@ -75,7 +75,7 @@ doc_crud_test_() ->
 
 
 setup() ->
-    Ctx = test_util:start_couch([fabric]),
+    Ctx = test_util:start_couch([fabric, couch_js]),
     {ok, Db} = fabric2_db:create(?tempdb(), [{user_ctx, ?ADMIN_USER}]),
     {Db, Ctx}.
 
diff --git a/src/mango/src/mango_eval.erl b/src/mango/src/mango_eval.erl
index 59d784b..7fd81df 100644
--- a/src/mango/src/mango_eval.erl
+++ b/src/mango/src/mango_eval.erl
@@ -18,7 +18,10 @@
 -export([
     acquire_map_context/1,
     release_map_context/1,
-    map_docs/2
+    map_docs/2,
+    acquire_context/0,
+    release_context/1,
+    try_compile/4
 ]).
 
 
@@ -60,6 +63,18 @@ map_docs(Indexes, Docs) ->
     end, Docs)}.
 
 
+acquire_context() ->
+    {ok, no_ctx}.
+
+
+release_context(_) ->
+    ok.
+
+
+try_compile(_Ctx, _FunType, _IndexName, IndexInfo) ->
+    mango_idx_view:validate_index_def(IndexInfo).
+
+
 index_doc(Indexes, Doc) ->
     lists:map(fun(Idx) ->
         {IdxDef} = mango_idx:def(Idx),
diff --git a/test/elixir/lib/setup/common.ex b/test/elixir/lib/setup/common.ex
index e81f109..65cd04f 100644
--- a/test/elixir/lib/setup/common.ex
+++ b/test/elixir/lib/setup/common.ex
@@ -19,9 +19,9 @@ defmodule Couch.Test.Setup.Common do
       |> Step.Create.DB.new(:db)
   end
 
-  def with_db(setup) do
+  def with_db(setup, apps \\ []) do
     setup
-      |> Step.Start.new(:start, extra_apps: [:fabric])
+      |> Step.Start.new(:start, extra_apps: [:fabric] ++ apps)
       |> Step.Create.DB.new(:db)
   end
 end
\ No newline at end of file

[couchdb] 02/02: remove couch_index_server:validate

Posted by ga...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

garren pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 8843083046ad28b4c987ac4da580103eb43fa15c
Author: garren smith <ga...@gmail.com>
AuthorDate: Wed Mar 31 10:39:55 2021 +0200

    remove couch_index_server:validate
    
    This makes it that the only way to validate a design doc is
    through couch_mrview:validate_ddoc so that the correct couch_eval
    will be used.
---
 src/couch/src/couch_db.erl                 |  2 +-
 src/couch_index/src/couch_index_server.erl | 21 +--------------------
 2 files changed, 2 insertions(+), 21 deletions(-)

diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl
index 60d2bb7..6587205 100644
--- a/src/couch/src/couch_db.erl
+++ b/src/couch/src/couch_db.erl
@@ -895,7 +895,7 @@ validate_doc_update(Db, Doc, GetDiskDocFun) ->
 
 validate_ddoc(Db, DDoc) ->
     try
-        ok = couch_index_server:validate(Db, couch_doc:with_ejson_body(DDoc))
+        ok = couch_mrview:validate(Db, couch_doc:with_ejson_body(DDoc))
     catch
         throw:{invalid_design_doc, Reason} ->
             {bad_request, invalid_design_doc, Reason};
diff --git a/src/couch_index/src/couch_index_server.erl b/src/couch_index/src/couch_index_server.erl
index 6bebff2..de2fa1c 100644
--- a/src/couch_index/src/couch_index_server.erl
+++ b/src/couch_index/src/couch_index_server.erl
@@ -16,7 +16,7 @@
 
 -vsn(2).
 
--export([start_link/0, validate/2, get_index/4, get_index/3, get_index/2]).
+-export([start_link/0, get_index/4, get_index/3, get_index/2]).
 
 -export([init/1, terminate/2, code_change/3]).
 -export([handle_call/3, handle_cast/2, handle_info/2]).
@@ -41,25 +41,6 @@ start_link() ->
     gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
 
 
-validate(Db, DDoc) ->
-    LoadModFun = fun
-        ({ModNameList, "true"}) ->
-            try
-                [list_to_existing_atom(ModNameList)]
-            catch error:badarg ->
-                []
-            end;
-        ({_ModNameList, _Enabled}) ->
-            []
-    end,
-    ValidateFun = fun
-        (ModName) ->
-            ModName:validate(Db, DDoc)
-    end,
-    EnabledIndexers = lists:flatmap(LoadModFun, config:get("indexers")),
-    lists:foreach(ValidateFun, EnabledIndexers).
-
-
 get_index(Module, <<"shards/", _/binary>> = DbName, DDoc)
         when is_record(DDoc, doc) ->
     get_index(Module, DbName, DDoc, nil);