You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ro...@apache.org on 2015/02/03 16:13:47 UTC
[40/50] [abbrv] couchdb-mango git commit: Implement the _explain
endpoint
Implement the _explain endpoint
This returns a JSON blob describing a provided query. It accepts the
same exact POST body parameters as _find but instead of returning query
results it returns a description of the query that would be executed.
This is intended for debugging purposes.
BugzId: 33294
Project: http://git-wip-us.apache.org/repos/asf/couchdb-mango/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mango/commit/812cf6bd
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mango/tree/812cf6bd
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mango/diff/812cf6bd
Branch: refs/heads/master
Commit: 812cf6bd043f4c9f9b93f0f7eebca4a05df3b2ec
Parents: 06bf775
Author: Paul J. Davis <pa...@gmail.com>
Authored: Fri Jan 9 15:43:51 2015 -0600
Committer: Paul J. Davis <pa...@gmail.com>
Committed: Fri Jan 16 13:32:50 2015 -0600
----------------------------------------------------------------------
src/mango_crud.erl | 10 +++++++++-
src/mango_cursor.erl | 23 +++++++++++++++++++++++
src/mango_cursor_view.erl | 12 ++++++++++++
src/mango_httpd.erl | 12 ++++++++++++
test/mango.py | 13 ++++++++++---
5 files changed, 66 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/812cf6bd/src/mango_crud.erl
----------------------------------------------------------------------
diff --git a/src/mango_crud.erl b/src/mango_crud.erl
index 159d5f7..68c9d6c 100644
--- a/src/mango_crud.erl
+++ b/src/mango_crud.erl
@@ -16,7 +16,8 @@
insert/3,
find/5,
update/4,
- delete/3
+ delete/3,
+ explain/3
]).
-export([
@@ -98,6 +99,13 @@ delete(Db, Selector, Options) ->
end.
+explain(Db, Selector, Opts0) ->
+ Opts1 = maybe_add_user_ctx(Db, Opts0),
+ Opts2 = maybe_int_to_str(r, Opts1),
+ {ok, Cursor} = mango_cursor:create(Db, Selector, Opts2),
+ mango_cursor:explain(Cursor).
+
+
maybe_add_user_ctx(Db, Opts) ->
case lists:keyfind(user_ctx, 1, Opts) of
{user_ctx, _} ->
http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/812cf6bd/src/mango_cursor.erl
----------------------------------------------------------------------
diff --git a/src/mango_cursor.erl b/src/mango_cursor.erl
index 5bfe383..d4d5523 100644
--- a/src/mango_cursor.erl
+++ b/src/mango_cursor.erl
@@ -15,6 +15,7 @@
-export([
create/3,
+ explain/1,
execute/3
]).
@@ -49,6 +50,28 @@ create(Db, Selector0, Opts) ->
create_cursor(Db, UsableIndexes, Selector, Opts).
+explain(#cursor{}=Cursor) ->
+ #cursor{
+ index = Idx,
+ selector = Selector,
+ opts = Opts0,
+ limit = Limit,
+ skip = Skip,
+ fields = Fields
+ } = Cursor,
+ Mod = mango_idx:cursor_mod(Idx),
+ Opts = lists:keydelete(user_ctx, 1, Opts0),
+ {[
+ {dbname, mango_idx:dbname(Idx)},
+ {index, mango_idx:to_json(Idx)},
+ {selector, Selector},
+ {opts, {Opts}},
+ {limit, Limit},
+ {skip, Skip},
+ {fields, Fields}
+ ] ++ Mod:explain(Cursor)}.
+
+
execute(#cursor{index=Idx}=Cursor, UserFun, UserAcc) ->
Mod = mango_idx:cursor_mod(Idx),
Mod:execute(Cursor, UserFun, UserAcc).
http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/812cf6bd/src/mango_cursor_view.erl
----------------------------------------------------------------------
diff --git a/src/mango_cursor_view.erl b/src/mango_cursor_view.erl
index 798b713..b32353d 100644
--- a/src/mango_cursor_view.erl
+++ b/src/mango_cursor_view.erl
@@ -14,6 +14,7 @@
-export([
create/4,
+ explain/1,
execute/3
]).
@@ -47,6 +48,17 @@ create(Db, Indexes, Selector, Opts) ->
}}.
+explain(Cursor) ->
+ #cursor{
+ index = Idx,
+ ranges = Ranges
+ } = Cursor,
+ [{range, {[
+ {start_key, mango_idx:start_key(Idx, Ranges)},
+ {end_key, mango_idx:end_key(Idx, Ranges)}
+ ]}}].
+
+
execute(#cursor{db = Db, index = Idx} = Cursor0, UserFun, UserAcc) ->
Cursor = Cursor0#cursor{
user_fun = UserFun,
http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/812cf6bd/src/mango_httpd.erl
----------------------------------------------------------------------
diff --git a/src/mango_httpd.erl b/src/mango_httpd.erl
index 02e26ad..ed1e9bc 100644
--- a/src/mango_httpd.erl
+++ b/src/mango_httpd.erl
@@ -41,6 +41,8 @@ handle_req(#httpd{} = Req, Db0) ->
handle_req_int(#httpd{path_parts=[_, <<"_index">> | _]} = Req, Db) ->
handle_index_req(Req, Db);
+handle_req_int(#httpd{path_parts=[_, <<"_explain">> | _]} = Req, Db) ->
+ handle_explain_req(Req, Db);
handle_req_int(#httpd{path_parts=[_, <<"_find">> | _]} = Req, Db) ->
handle_find_req(Req, Db);
handle_req_int(_, _) ->
@@ -119,6 +121,16 @@ handle_index_req(Req, _Db) ->
chttpd:send_method_not_allowed(Req, "GET,POST,DELETE").
+handle_explain_req(#httpd{method='POST'}=Req, Db) ->
+ {ok, Opts0} = mango_opts:validate_find(chttpd:json_body_obj(Req)),
+ {value, {selector, Sel}, Opts} = lists:keytake(selector, 1, Opts0),
+ Resp = mango_crud:explain(Db, Sel, Opts),
+ chttpd:send_json(Req, Resp);
+
+handle_explain_req(Req, _Db) ->
+ chttpd:send_method_not_allowed(Req, "POST").
+
+
handle_find_req(#httpd{method='POST'}=Req, Db) ->
{ok, Opts0} = mango_opts:validate_find(chttpd:json_body_obj(Req)),
{value, {selector, Sel}, Opts} = lists:keytake(selector, 1, Opts0),
http://git-wip-us.apache.org/repos/asf/couchdb-mango/blob/812cf6bd/test/mango.py
----------------------------------------------------------------------
diff --git a/test/mango.py b/test/mango.py
index c28f280..fac4e7e 100644
--- a/test/mango.py
+++ b/test/mango.py
@@ -107,7 +107,7 @@ class Database(object):
r.raise_for_status()
def find(self, selector, limit=25, skip=0, sort=None, fields=None,
- r=1, conflicts=False):
+ r=1, conflicts=False, explain=False):
body = {
"selector": selector,
"limit": limit,
@@ -120,9 +120,16 @@ class Database(object):
if fields is not None:
body["fields"] = fields
body = json.dumps(body)
- r = self.sess.post(self.path("_find"), data=body)
+ if explain:
+ path = self.path("_explain")
+ else:
+ path = self.path("_find")
+ r = self.sess.post(path, data=body)
r.raise_for_status()
- return r.json()["docs"]
+ if explain:
+ return r.json()
+ else:
+ return r.json()["docs"]
def find_one(self, *args, **kwargs):
results = self.find(*args, **kwargs)