This is an automated email from the ASF dual-hosted git repository. jan pushed a commit to branch rebase/access-2023 in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 5f7c075cc01b26ccc1bfc76669c4d8648569f204 Author: Jan Lehnardt <[email protected]> AuthorDate: Fri Jun 24 17:18:11 2022 +0200 feat(access): add access query server --- src/couch/src/couch_access_native_proc.erl | 143 +++++++++++++++++++++++++++++ src/couch/src/couch_proc_manager.erl | 1 + 2 files changed, 144 insertions(+) diff --git a/src/couch/src/couch_access_native_proc.erl b/src/couch/src/couch_access_native_proc.erl new file mode 100644 index 000000000..965b124de --- /dev/null +++ b/src/couch/src/couch_access_native_proc.erl @@ -0,0 +1,143 @@ +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-module(couch_access_native_proc). +-behavior(gen_server). + + +-export([ + start_link/0, + set_timeout/2, + prompt/2 +]). + +-export([ + init/1, + terminate/2, + handle_call/3, + handle_cast/2, + handle_info/2, + code_change/3 +]). + + +-record(st, { + indexes = [], + timeout = 5000 % TODO: make configurable +}). + +start_link() -> + gen_server:start_link(?MODULE, [], []). + + +set_timeout(Pid, TimeOut) when is_integer(TimeOut), TimeOut > 0 -> + gen_server:call(Pid, {set_timeout, TimeOut}). + + +prompt(Pid, Data) -> + gen_server:call(Pid, {prompt, Data}). + + +init(_) -> + {ok, #st{}}. + + +terminate(_Reason, _St) -> + ok. + + +handle_call({set_timeout, TimeOut}, _From, St) -> + {reply, ok, St#st{timeout=TimeOut}}; + +handle_call({prompt, [<<"reset">>]}, _From, St) -> + {reply, true, St#st{indexes=[]}}; + +handle_call({prompt, [<<"reset">>, _QueryConfig]}, _From, St) -> + {reply, true, St#st{indexes=[]}}; + +handle_call({prompt, [<<"add_fun">>, IndexInfo]}, _From, St) -> + {reply, true, St}; + +handle_call({prompt, [<<"map_doc">>, Doc]}, _From, St) -> + {reply, map_doc(St, mango_json:to_binary(Doc)), St}; + +handle_call({prompt, [<<"reduce">>, _, _]}, _From, St) -> + {reply, null, St}; + +handle_call({prompt, [<<"rereduce">>, _, _]}, _From, St) -> + {reply, null, St}; + +handle_call({prompt, [<<"index_doc">>, Doc]}, _From, St) -> + {reply, [[]], St}; + +handle_call(Msg, _From, St) -> + {stop, {invalid_call, Msg}, {invalid_call, Msg}, St}. + +handle_cast(garbage_collect, St) -> + erlang:garbage_collect(), + {noreply, St}; + +handle_cast(Msg, St) -> + {stop, {invalid_cast, Msg}, St}. + + +handle_info(Msg, St) -> + {stop, {invalid_info, Msg}, St}. + + +code_change(_OldVsn, St, _Extra) -> + {ok, St}. + +% return value is an array of arrays, first dimension is the different indexes +% [0] will be by-access-id // for this test, later we should make this by-access +% -seq, since that one we will always need, and by-access-id can be opt-in. +% the second dimension is the number of emit kv pairs: +% [ // the return value +% [ // the first view +% ['k1', 'v1'], // the first k/v pair for the first view +% ['k2', 'v2'] // second, etc. +% ], +% [ // second view +% ['l1', 'w1'] // first k/v par in second view +% ] +% ] +% {"id":"account/bongel","key":"account/bongel","value":{"rev":"1-967a00dff5e02add41819138abb3284d"}}, + +map_doc(_St, {Doc}) -> + case couch_util:get_value(<<"_access">>, Doc) of + undefined -> + [[],[]]; % do not index this doc + Access when is_list(Access) -> + Id = couch_util:get_value(<<"_id">>, Doc), + Rev = couch_util:get_value(<<"_rev">>, Doc), + Seq = couch_util:get_value(<<"_seq">>, Doc), + Deleted = couch_util:get_value(<<"_deleted">>, Doc, false), + BodySp = couch_util:get_value(<<"_body_sp">>, Doc), + % by-access-id + ById = case Deleted of + false -> + lists:map(fun(UserOrRole) -> [ + [[UserOrRole, Id], Rev] + ] end, Access); + _True -> [[]] + end, + + % by-access-seq + BySeq = lists:map(fun(UserOrRole) -> [ + [[UserOrRole, Seq], [{rev, Rev}, {deleted, Deleted}, {body_sp, BodySp}]] + ] end, Access), + ById ++ BySeq; + Else -> + % TODO: no comprende: should not be needed once we implement + % _access field validation + [[],[]] + end. diff --git a/src/couch/src/couch_proc_manager.erl b/src/couch/src/couch_proc_manager.erl index 623734e6e..e3396ab15 100644 --- a/src/couch/src/couch_proc_manager.erl +++ b/src/couch/src/couch_proc_manager.erl @@ -144,6 +144,7 @@ init([]) -> ets:insert(?SERVERS, get_servers_from_env("COUCHDB_QUERY_SERVER_")), ets:insert(?SERVERS, get_servers_from_env("COUCHDB_NATIVE_QUERY_SERVER_")), ets:insert(?SERVERS, [{"QUERY", {mango_native_proc, start_link, []}}]), + ets:insert(?SERVERS, [{"_ACCESS", {couch_access_native_proc, start_link, []}}]), maybe_configure_erlang_native_servers(), {ok, #state{
