summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2019-11-11 20:15:09 +0000
committerRobert Newson <rnewson@apache.org>2019-11-21 18:22:24 +0000
commit3522f167ed7b29aafe6b4a7f51bbc15bc428add5 (patch)
treeb3d4a9c22fbd7b8f394b06fda7addf971235df8c
parentba6cd467f5f812d785039b6a5bedf0d135e4fc5b (diff)
downloadcouchdb-1523-bye-bye-5986-rnewson.tar.gz
WIP Add remaining endpoints1523-bye-bye-5986-rnewson
-rw-r--r--src/chttpd/src/chttpd_node.erl104
1 files changed, 93 insertions, 11 deletions
diff --git a/src/chttpd/src/chttpd_node.erl b/src/chttpd/src/chttpd_node.erl
index c560e0e2c..63e073527 100644
--- a/src/chttpd/src/chttpd_node.erl
+++ b/src/chttpd/src/chttpd_node.erl
@@ -13,10 +13,19 @@
-module(chttpd_node).
-compile(tuple_calls).
+%% Public API
+-export([
+ handle_node_req/1
+]).
+
+%% for inter-node calls
-export([
- handle_node_req/1,
do_db_req/4,
- get_stats/0
+ do_db_req/5,
+ get_stats/0,
+ compact_view/2,
+ design_doc_info/2,
+ view_info/3
]).
-include_lib("couch/include/couch_db.hrl").
@@ -176,14 +185,63 @@ handle_node_db_req(#httpd{method='GET', path_parts=[DbName]}=Req, Node) ->
handle_node_db_req(#httpd{path_parts=[_DbName]}=Req, _Node) ->
send_method_not_allowed(Req, "GET");
-%{'GET', DbName, [<<"_all_docs">>]} ->
-% ...
-%{'POST', DbName, [<<"_compact">>]} ->
-% ...
-%{_, DbName, [DocName]} ->
-% %only support doc CRUD in _dbs/_nodes, and _info endpoint on all
-%{'GET', DbName, [<<"_design">>, DDoc, <<"_info">>]} ->
-% %individual view shard info stats
+handle_node_db_req(#httpd{path_parts=[_DbName, <<"_all_docs">>]}=Req, _Node) ->
+ send_json(Req, 200, {[]});
+
+handle_node_db_req(#httpd{method='POST', path_parts=[DbName, <<"_compact">>]}=Req, Node) ->
+ chttpd:validate_ctype(Req, "application/json"),
+ case call_node(Node, chttpd_node, do_db_req,
+ [Req#httpd.user_ctx, DbName, couch_db, start_compact]) of
+ {ok, _} ->
+ send_json(Req, 202, {[{ok, true}]});
+ {not_found, _} ->
+ send_error(Req, not_found)
+ end;
+
+handle_node_db_req(#httpd{method='POST', path_parts=[DbName, <<"_compact">>, DesignName]}=Req, Node) ->
+ chttpd:validate_ctype(Req, "application/json"),
+ DesignId = <<"_design/", DesignName/binary>>,
+ case call_node(Node, chttpd_node, do_db_req,
+ [Req#httpd.user_ctx, DbName, chttpd_node, compact_view, [DesignId]]) of
+ ok ->
+ send_json(Req, 202, {[{ok, true}]});
+ {not_found, _} ->
+ send_error(Req, not_found)
+ end;
+
+handle_node_db_req(#httpd{path_parts=[_DbName, <<"_", _/binary>> = EP]}=Req, _Node) ->
+ send_error(Req, {forbidden, <<EP/binary, " endpoint is not permitted.">>});
+
+handle_node_db_req(#httpd{path_parts=[<<"shards/", _/binary>>, _DocID]}=Req, _Node) ->
+ send_error(Req, {forbidden, <<"Document CRUD not permitted within shards.">>});
+
+handle_node_db_req(#httpd{path_parts=[_DbName, DocID]}=Req, _Node) ->
+ send_json(Req, 200, {[]});
+
+handle_node_db_req(#httpd{path_parts=[_DbName, <<"_design">>, DDocID]}=Req, _Node) ->
+ send_json(Req, 200, {[]});
+
+handle_node_db_req(#httpd{method='GET',
+ path_parts=[DbName, <<"_design">>, DesignName, <<"_info">>]}=Req, Node) ->
+ DesignId = <<"_design/", DesignName/binary>>,
+ case call_node(Node, chttpd_node, do_db_req,
+ [Req#httpd.user_ctx, DbName, chttpd_node, design_doc_info, [DesignId]]) of
+ {ok, Info} ->
+ send_json(Req, 200, {Info});
+ {not_found, _} ->
+ send_error(Req, not_found)
+ end;
+
+handle_node_db_req(#httpd{method='GET',
+ path_parts=[DbName, <<"_design">>, DesignName, <<"_view">>, VName, <<"_info">>]}=Req, Node) ->
+ DesignId = <<"_design/", DesignName/binary>>,
+ case call_node(Node, chttpd_node, do_db_req,
+ [Req#httpd.user_ctx, DbName, chttpd_node, view_info, [DesignId, VName]]) of
+ {ok, Info} ->
+ send_json(Req, 200, {Info});
+ {not_found, _} ->
+ send_error(Req, not_found)
+ end;
handle_node_db_req(Req, _Node) ->
send_error(Req, {bad_request, <<"invalid _node request">>}).
@@ -191,10 +249,13 @@ handle_node_db_req(Req, _Node) ->
% below adapted from old couch_httpd_db
% all of these run on the requested node
do_db_req(Ctx, DbName, Mod, Fun) ->
+ do_db_req(Ctx, DbName, Mod, Fun, []).
+
+do_db_req(Ctx, DbName, Mod, Fun, Args) ->
case couch_db:open(DbName, [{user_ctx, Ctx}]) of
{ok, Db} ->
try
- erlang:apply(Mod, Fun, [Db])
+ erlang:apply(Mod, Fun, [Db | Args])
after
catch couch_db:close(Db)
end;
@@ -221,6 +282,27 @@ call_node(Node, Mod, Fun, Args) when is_atom(Node) ->
Else
end.
+compact_view(Db, DesignId) ->
+ DDoc = couch_httpd_db:couch_doc_open(
+ Db, DesignId, nil, [ejson_body]),
+ couch_mrview:compact(Db, DDoc).
+
+
+design_doc_info(Db, DesignId) ->
+ DDoc = couch_httpd_db:couch_doc_open(
+ Db, DesignId, nil, [ejson_body]),
+ fabric:get_view_group_info(Db, DDoc).
+
+
+view_info(Db, DDocId, VName) ->
+ DbName = couch_db:name(Db),
+ {ok, Info} = couch_mrview:get_view_info(DbName, DDocId, VName),
+ FinalInfo = [{db_name, DbName},
+ {ddoc, DDocId},
+ {view, VName} | Info],
+ {ok, FinalInfo}.
+
+
flush(Node, Req) ->
case couch_util:get_value("flush", chttpd:qs(Req)) of
"true" ->