You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by be...@apache.org on 2011/04/06 10:55:46 UTC

svn commit: r1089361 - in /couchdb/trunk: share/www/script/test/rewrite.js src/couchdb/couch_httpd_rewrite.erl

Author: benoitc
Date: Wed Apr  6 08:55:45 2011
New Revision: 1089361

URL: http://svn.apache.org/viewvc?rev=1089361&view=rev
Log:
add formating in variables substitution:
     {
         "from": "simpleForm/basicViewPath/:start/:end",
         "to": "_list/simpleForm/basicView",
         "query": {
             "startkey": ":start",
             "endkey": ":end"
         },
         "formats": {
             "start": "int",
             "end": "int"
         }
     },

add tests for integer and boolean cases. Fix issue #COUCHDB-1074 .

Modified:
    couchdb/trunk/share/www/script/test/rewrite.js
    couchdb/trunk/src/couchdb/couch_httpd_rewrite.erl

Modified: couchdb/trunk/share/www/script/test/rewrite.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/rewrite.js?rev=1089361&r1=1089360&r2=1089361&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/rewrite.js (original)
+++ couchdb/trunk/share/www/script/test/rewrite.js Wed Apr  6 08:55:45 2011
@@ -114,6 +114,18 @@ couchTests.rewrite = function(debug) {
               }
             },
             {
+              "from": "simpleForm/basicViewPath/:start/:end",
+              "to": "_list/simpleForm/basicView",
+              "query": {
+                "startkey": ":start",
+                "endkey": ":end"
+              },
+              "formats": {
+                "start": "int",
+                "end": "int"
+              }
+            },
+            {
               "from": "simpleForm/complexView",
               "to": "_list/simpleForm/complexView",
               "query": {
@@ -156,6 +168,18 @@ couchTests.rewrite = function(debug) {
               }
             },
             {
+              "from": "simpleForm/complexView7/:a/:b",
+              "to": "_view/complexView3",
+              "query": {
+                "key": [":a", ":b"],
+                "include_docs": ":doc"
+              },
+              "format": {
+                "doc": "bool"
+              }
+
+            },
+            {
               "from": "/",
               "to": "_view/basicView",
             }
@@ -340,7 +364,14 @@ couchTests.rewrite = function(debug) {
         T(!(/Key: 1/.test(xhr.responseText)));
         T(/FirstKey: 3/.test(xhr.responseText));
         T(/LastKey: 8/.test(xhr.responseText));
-        
+       
+        // get with query params
+        xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/basicViewPath/3/8");
+        T(xhr.status == 200, "with query params");
+        T(!(/Key: 1/.test(xhr.responseText)));
+        T(/FirstKey: 3/.test(xhr.responseText));
+        T(/LastKey: 8/.test(xhr.responseText));
+
         // get with query params        
         xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/complexView");
         T(xhr.status == 200, "with query params");
@@ -365,6 +396,11 @@ couchTests.rewrite = function(debug) {
         xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/complexView6?a=test&b=essai");
         T(xhr.status == 200, "with query params");
         T(/Value: doc 4/.test(xhr.responseText));
+
+        xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/complexView7/test/essai?doc=true");
+        T(xhr.status == 200, "with query params");
+        var result = JSON.parse(xhr.responseText);
+        T(typeof(result.rows[0].doc) === "object");
         
         // test path relative to server
         designDoc.rewrites.push({

Modified: couchdb/trunk/src/couchdb/couch_httpd_rewrite.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_rewrite.erl?rev=1089361&r1=1089360&r2=1089361&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_rewrite.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_rewrite.erl Wed Apr  6 08:55:45 2011
@@ -197,7 +197,7 @@ quote_plus(X) ->
 try_bind_path([], _Method, _PathParts, _QueryList) ->
     no_dispatch_path;
 try_bind_path([Dispatch|Rest], Method, PathParts, QueryList) ->
-    [{PathParts1, Method1}, RedirectPath, QueryArgs] = Dispatch,
+    [{PathParts1, Method1}, RedirectPath, QueryArgs, Formats] = Dispatch,
     case bind_method(Method1, Method) of
         true ->
             case bind_path(PathParts1, PathParts, []) of
@@ -205,7 +205,8 @@ try_bind_path([Dispatch|Rest], Method, P
                     Bindings1 = Bindings ++ QueryList,
                     % we parse query args from the rule and fill
                     % it eventually with bindings vars
-                    QueryArgs1 = make_query_list(QueryArgs, Bindings1, []),
+                    QueryArgs1 = make_query_list(QueryArgs, Bindings1,
+                        Formats, []),
                     % remove params in QueryLists1 that are already in
                     % QueryArgs1
                     Bindings2 = lists:foldl(fun({K, V}, Acc) ->
@@ -231,34 +232,34 @@ try_bind_path([Dispatch|Rest], Method, P
 %% rewriting dynamically the quey list given as query member in
 %% rewrites. Each value is replaced by one binding or an argument
 %% passed in url.
-make_query_list([], _Bindings, Acc) ->
+make_query_list([], _Bindings, _Formats, Acc) ->
     Acc;
-make_query_list([{Key, {Value}}|Rest], Bindings, Acc) ->
+make_query_list([{Key, {Value}}|Rest], Bindings, Formats, Acc) ->
     Value1 = {Value},
-    make_query_list(Rest, Bindings, [{to_binding(Key), Value1}|Acc]);
-make_query_list([{Key, Value}|Rest], Bindings, Acc) when is_binary(Value) ->
-    Value1 = replace_var(Value, Bindings),
-    make_query_list(Rest, Bindings, [{to_binding(Key), Value1}|Acc]);
-make_query_list([{Key, Value}|Rest], Bindings, Acc) when is_list(Value) ->
-    Value1 = replace_var(Value, Bindings),
-    make_query_list(Rest, Bindings, [{to_binding(Key), Value1}|Acc]);
-make_query_list([{Key, Value}|Rest], Bindings, Acc) ->
-    make_query_list(Rest, Bindings, [{to_binding(Key), Value}|Acc]).
-
-replace_var(<<"*">>=Value, Bindings) ->
-    get_var(Value, Bindings, Value);
-replace_var(<<":", Var/binary>> = Value, Bindings) ->
-    get_var(Var, Bindings, Value);
-replace_var(Value, _Bindings) when is_binary(Value) ->
+    make_query_list(Rest, Bindings, Formats, [{to_binding(Key), Value1}|Acc]);
+make_query_list([{Key, Value}|Rest], Bindings, Formats, Acc) when is_binary(Value) ->
+    Value1 = replace_var(Value, Bindings, Formats),
+    make_query_list(Rest, Bindings, Formats, [{to_binding(Key), Value1}|Acc]);
+make_query_list([{Key, Value}|Rest], Bindings, Formats, Acc) when is_list(Value) ->
+    Value1 = replace_var(Value, Bindings, Formats),
+    make_query_list(Rest, Bindings, Formats, [{to_binding(Key), Value1}|Acc]);
+make_query_list([{Key, Value}|Rest], Bindings, Formats, Acc) ->
+    make_query_list(Rest, Bindings, Formats, [{to_binding(Key), Value}|Acc]).
+
+replace_var(<<"*">>=Value, Bindings, Formats) ->
+    get_var(Value, Bindings, Value, Formats);
+replace_var(<<":", Var/binary>> = Value, Bindings, Formats) ->
+    get_var(Var, Bindings, Value, Formats);
+replace_var(Value, _Bindings, _Formats) when is_binary(Value) ->
     Value;
-replace_var(Value, Bindings) when is_list(Value) ->
+replace_var(Value, Bindings, Formats) when is_list(Value) ->
     lists:reverse(lists:foldl(fun
                 (<<":", Var/binary>>=Value1, Acc) ->
-                    [get_var(Var, Bindings, Value1)|Acc];
+                    [get_var(Var, Bindings, Value1, Formats)|Acc];
                 (Value1, Acc) ->
                     [Value1|Acc]
             end, [], Value));
-replace_var(Value, _Bindings) ->
+replace_var(Value, _Bindings, _Formats) ->
     Value.
                     
 maybe_json(Key, Value) ->
@@ -270,10 +271,40 @@ maybe_json(Key, Value) ->
             Value
     end.
 
-get_var(VarName, Props, Default) ->
+get_var(VarName, Props, Default, Formats) ->
     VarName1 = to_binding(VarName),
     Val = couch_util:get_value(VarName1, Props, Default),
-    Val.
+    maybe_format(VarName, Val, Formats).
+
+maybe_format(VarName, Value, Formats) ->
+    case couch_util:get_value(VarName, Formats) of
+        undefined ->
+             Value;
+        Format ->
+            format(Format, Value)
+    end.
+
+format(<<"int">>, Value) when is_integer(Value) ->
+    Value;
+format(<<"int">>, Value) when is_binary(Value) ->
+    format(<<"int">>, ?b2l(Value));
+format(<<"int">>, Value) when is_list(Value) ->
+    case (catch list_to_integer(Value)) of
+        IntVal when is_integer(IntVal) ->
+            IntVal;
+        _ ->
+            Value
+    end;
+format(<<"bool">>, Value) when is_binary(Value) ->
+    format(<<"bool">>, ?b2l(Value));
+format(<<"bool">>, Value) when is_list(Value) ->
+    case string:to_lower(Value) of
+        "true" -> true;
+        "false" -> false;
+        _ -> Value
+    end;
+format(_Format, Value) ->
+   Value. 
 
 %% doc: build new patch from bindings. bindings are query args
 %% (+ dynamic query rewritten if needed) and bindings found in
@@ -367,7 +398,11 @@ make_rule(Rule) ->
         To ->
             parse_path(To)
         end,
-    [{FromParts, Method}, ToParts, QueryArgs].
+    Formats = case couch_util:get_value(<<"formats">>, Rule) of
+        undefined -> [];
+        {Fmts} -> Fmts
+    end,
+    [{FromParts, Method}, ToParts, QueryArgs, Formats].
 
 parse_path(Path) ->
     {ok, SlashRE} = re:compile(<<"\\/">>),
@@ -404,7 +439,7 @@ maybe_encode_bindings([]) ->
     [];
 maybe_encode_bindings(Props) -> 
     lists:foldl(fun 
-            ({{bind, <<"*">>}, V}, Acc) ->
+            ({{bind, <<"*">>}, _V}, Acc) ->
                 Acc;
             ({{bind, K}, V}, Acc) ->
                 V1 = iolist_to_binary(maybe_json(K, V)),