summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/www/script/test/rewrite.js104
-rw-r--r--src/couchdb/couch_httpd_rewrite.erl35
2 files changed, 112 insertions, 27 deletions
diff --git a/share/www/script/test/rewrite.js b/share/www/script/test/rewrite.js
index 48e5edb4..46e7e477 100644
--- a/share/www/script/test/rewrite.js
+++ b/share/www/script/test/rewrite.js
@@ -67,12 +67,19 @@ couchTests.rewrite = function(debug) {
}
},
{
- "from": "/welcome2/:name",
+ "from": "/welcome2",
+ "to": "_show/welcome",
+ "query": {
+ "name": "user"
+ }
+ },
+ {
+ "from": "/welcome3/:name",
"to": "_update/welcome2/:name",
"method": "PUT"
},
{
- "from": "/welcome2/:name",
+ "from": "/welcome3/:name",
"to": "_show/welcome2/:name",
"method": "GET"
},
@@ -95,8 +102,37 @@ couchTests.rewrite = function(debug) {
"startkey": ":start",
"endkey": ":end"
}
+ },
+ {
+ "from": "simpleForm/complexView",
+ "to": "_list/simpleForm/complexView",
+ "query": {
+ "key": [1, 2]
+ }
+ },
+ {
+ "from": "simpleForm/complexView2",
+ "to": "_list/simpleForm/complexView",
+ "query": {
+ "key": ["test", {}]
+ }
+ },
+ {
+ "from": "simpleForm/complexView3",
+ "to": "_list/simpleForm/complexView",
+ "query": {
+ "key": ["test", ["test", "essai"]]
+ }
+ },
+ {
+ "from": "simpleForm/complexView4",
+ "to": "_list/simpleForm/complexView2",
+ "query": {
+ "key": {"c": 1}
+ }
}
+
],
lists: {
simpleForm: stringFun(function(head, req) {
@@ -112,7 +148,7 @@ couchTests.rewrite = function(debug) {
+' LineNo: '+row_number+'</li>');
}
return '</ul><p>FirstKey: '+ firstKey + ' LastKey: '+ prevKey+'</p>';
- })
+ }),
},
shows: {
"welcome": stringFun(function(doc,req) {
@@ -152,7 +188,24 @@ couchTests.rewrite = function(debug) {
views : {
basicView : {
map : stringFun(function(doc) {
- emit(doc.integer, doc.string);
+ if (doc.integer) {
+ emit(doc.integer, doc.string);
+ }
+
+ })
+ },
+ complexView: {
+ map: stringFun(function(doc) {
+ if (doc.type == "complex") {
+ emit([doc.a, doc.b], doc.string);
+ }
+ })
+ },
+ complexView2: {
+ map: stringFun(function(doc) {
+ if (doc.type == "complex") {
+ emit(doc.a, doc.string);
+ }
})
}
}
@@ -162,7 +215,17 @@ couchTests.rewrite = function(debug) {
var docs = makeDocs(0, 10);
db.bulkSave(docs);
-
+
+ var docs2 = [
+ {"a": 1, "b": 1, "string": "doc 1", "type": "complex"},
+ {"a": 1, "b": 2, "string": "doc 2", "type": "complex"},
+ {"a": "test", "b": {}, "string": "doc 3", "type": "complex"},
+ {"a": "test", "b": ["test", "essai"], "string": "doc 4", "type": "complex"},
+ {"a": {"c": 1}, "b": "", "string": "doc 5", "type": "complex"}
+ ];
+
+ db.bulkSave(docs2);
+
// test simple rewriting
req = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/foo");
@@ -190,21 +253,22 @@ couchTests.rewrite = function(debug) {
doc = db.open(docid);
T(doc.world == "hello");
- xhr = CouchDB.request("PUT", "/test_suite_db/_design/test/_rewrite/welcome2/test");
- T(xhr.status == 201);
- T(xhr.responseText == "New World");
- T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")));
-
- xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/welcome2/test");
- T(xhr.responseText == "Welcome test");
-
req = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/welcome?name=user");
T(req.responseText == "Welcome user");
req = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/welcome/user");
T(req.responseText == "Welcome user");
+ req = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/welcome2");
+ T(req.responseText == "Welcome user");
+
+ xhr = CouchDB.request("PUT", "/test_suite_db/_design/test/_rewrite/welcome3/test");
+ T(xhr.status == 201);
+ T(xhr.responseText == "New World");
+ T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")));
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/welcome3/test");
+ T(xhr.responseText == "Welcome test");
// get with query params
@@ -234,8 +298,22 @@ couchTests.rewrite = function(debug) {
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");
+ T(/FirstKey: [1, 2]/.test(xhr.responseText));
+
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/complexView2");
+ T(xhr.status == 200, "with query params");
+ T(/Value: doc 3/.test(xhr.responseText));
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_rewrite/simpleForm/complexView3");
+ 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/complexView4");
+ T(xhr.status == 200, "with query params");
+ T(/Value: doc 5/.test(xhr.responseText));
});
} \ No newline at end of file
diff --git a/src/couchdb/couch_httpd_rewrite.erl b/src/couchdb/couch_httpd_rewrite.erl
index 452873d9..364e6c4d 100644
--- a/src/couchdb/couch_httpd_rewrite.erl
+++ b/src/couchdb/couch_httpd_rewrite.erl
@@ -229,30 +229,32 @@ try_bind_path([Dispatch|Rest], Method, PathParts, QueryList) ->
make_query_list([], _Bindings, Acc) ->
Acc;
make_query_list([{Key, {Value}}|Rest], Bindings, Acc) ->
- Value1 = make_query_list(Value, Bindings, []),
+ Value1 = to_json({Value}),
make_query_list(Rest, Bindings, [{to_atom(Key), Value1}|Acc]);
make_query_list([{Key, Value}|Rest], Bindings, Acc) when is_binary(Value) ->
- Value1 = replace_var(Value, Bindings),
+ Value1 = replace_var(Key, Value, Bindings),
make_query_list(Rest, Bindings, [{to_atom(Key), Value1}|Acc]);
make_query_list([{Key, Value}|Rest], Bindings, Acc) when is_list(Value) ->
-
- Value1 = replace_vars(Value, Bindings, []),
+ Value1 = replace_var(Key, Value, Bindings),
make_query_list(Rest, Bindings, [{to_atom(Key), Value1}|Acc]);
make_query_list([{Key, Value}|Rest], Bindings, Acc) ->
make_query_list(Rest, Bindings, [{to_atom(Key), Value}|Acc]).
-replace_vars([], _Bindings, Acc) ->
- lists:reverse(Acc);
-replace_vars([V|R], Bindings, Acc) ->
- V1 = replace_var(V, Bindings),
- replace_vars(R, Bindings, [V1|Acc]).
-
-replace_var(Value, Bindings) ->
+replace_var(Key, Value, Bindings) ->
case Value of
<<":", Var/binary>> ->
Var1 = list_to_atom(binary_to_list(Var)),
proplists:get_value(Var1, Bindings, Value);
- _ -> Value
+ _ when is_binary(Value) ->
+ Value;
+ _ ->
+ case Key of
+ <<"key">> -> to_json(Value);
+ <<"startkey">> -> to_json(Value);
+ <<"endkey">> -> to_json(Value);
+ _ ->
+ lists:flatten(?JSON_ENCODE(Value))
+ end
end.
@@ -371,15 +373,17 @@ path_to_list([P|R], Acc) ->
path_to_list(R, [P1|Acc]).
encode_query(Props) ->
- RevPairs = lists:foldl(fun ({K, V}, Acc) ->
+ Props1 = lists:foldl(fun ({K, V}, Acc) ->
V1 = case is_list(V) of
true -> V;
+ false when is_binary(V) ->
+ V;
false ->
mochiweb_util:quote_plus(V)
end,
[{K, V1} | Acc]
end, [], Props),
- lists:flatten(mochiweb_util:urlencode(RevPairs)).
+ lists:flatten(mochiweb_util:urlencode(Props1)).
to_atom(V) when is_atom(V) ->
V;
@@ -387,3 +391,6 @@ to_atom(V) when is_binary(V) ->
to_atom(?b2l(V));
to_atom(V) ->
list_to_atom(V).
+
+to_json(V) ->
+ iolist_to_binary(?JSON_ENCODE(V)).