couchdb-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Bonser <mister...@gmail.com>
Subject [PATCH] Views: Multiple keys
Date Wed, 23 Jul 2008 05:36:24 GMT
After exploring the source code a bit and abandoning a few other ways of achieving this, I've
managed to get multi-key requests working. The only way to make it more efficient would require
some digging into the couch_btree folding code, I think.

You use it by POSTing a JSON array of keys to a view url. Any passed-in values for start_key
and end_key are ignored.

I haven't written any unittests for this yet, but I wanted to see what everyone else thinks
of this and ask if there's any obvious better way to accomplish the same goal.

This patch is against the latest in SVN as of now. Any comments or suggestions for this are
very much welcome.


Signed-off-by: Paul Bonser <misterpib@gmail.com>
--

diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl
index af8d9b4..c813a4c 100644
--- a/src/couchdb/couch_httpd.erl
+++ b/src/couchdb/couch_httpd.erl
@@ -363,6 +363,37 @@ handle_db_request(Req, 'GET', {DbName, _Db, ["_view", DocId, ViewName]})
->
         end
     end;
 
+% Multi-key request, with a JSON array of keys as the POST body
+handle_db_request(Req, 'POST', {DbName, _Db, ["_view", DocId, ViewName]}) ->
+    #view_query_args{
+        count = Count,
+        skip = SkipCount,
+        direction = Dir,
+        start_docid = StartDocId
+    } = QueryArgs = parse_view_query(Req),
+
+    case Req:get_primary_header_value("content-type") of
+        undefined -> ok;
+        "application/json" -> ok;
+        Else -> throw({incorrect_mime_type, Else})
+    end,
+	JsonKeys = tuple_to_list(cjson:decode(Req:recv_body())),
+
+    {ok, View} = couch_view:get_map_view({DbName, "_design/" ++ DocId, ViewName}),
+    {ok, RowCount} = couch_view:get_row_count(View),
+    FoldAccInit = {Count, SkipCount, undefined, []},
+    FoldResult = lists:foldl(fun(Key, {ok, FoldAcc}) ->
+        Start = {Key, StartDocId},
+        FoldlFun = make_view_fold_fun(Req, QueryArgs#view_query_args {
+                    start_key = Key,
+                    end_key = Key
+                }, 
+                RowCount, fun couch_view:reduce_to_count/1),
+        couch_view:fold(View, Start, Dir, FoldlFun, FoldAcc)
+    end, {ok, FoldAccInit}, JsonKeys),
+    finish_view_fold(Req, RowCount, FoldResult);
+
+
 handle_db_request(_Req, _Method, {_DbName, _Db, ["_view", _DocId, _ViewName]}) ->
     throw({method_not_allowed, "GET,HEAD"});
 

Mime
View raw message