summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjiangphcn <jiangph@cn.ibm.com>2018-01-15 18:16:19 +0800
committerPaul J. Davis <paul.joseph.davis@gmail.com>2018-01-26 14:38:04 -0600
commit1ecf363f2b6c1cdd937e449e084ca6e62eb343ff (patch)
tree893a5cfaab120f2850665deaaa87482b08005b54
parent380ae691d73b7a039fa0e14e2f74029a41f37289 (diff)
downloadcouchdb-1ecf363f2b6c1cdd937e449e084ca6e62eb343ff.tar.gz
Make _design_docs to respect query parameters
Fixes #1100
-rw-r--r--src/couch/src/couch_db.erl31
-rw-r--r--test/javascript/tests/design_docs_query.js154
2 files changed, 177 insertions, 8 deletions
diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl
index 5e720c284..b2b94ce80 100644
--- a/src/couch/src/couch_db.erl
+++ b/src/couch/src/couch_db.erl
@@ -1738,14 +1738,29 @@ do_pipe([Filter|Rest], F0) ->
set_namespace_range(Options, undefined) -> Options;
set_namespace_range(Options, NS) ->
- %% FIXME depending on order we might need to swap keys
- SK = select_gt(
- proplists:get_value(start_key, Options, <<"">>),
- <<NS/binary, "/">>),
- EK = select_lt(
- proplists:get_value(end_key, Options, <<NS/binary, "0">>),
- <<NS/binary, "0">>),
- [{start_key, SK}, {end_key_gt, EK}].
+ SK0 = proplists:get_value(start_key, Options, <<NS/binary, "/">>),
+ EKType = case proplists:get_value(end_key_gt, Options) of
+ undefined -> end_key;
+ _ -> end_key_gt
+ end,
+ EK0 = case EKType of
+ end_key ->
+ proplists:get_value(end_key, Options, <<NS/binary, "0">>);
+ end_key_gt ->
+ proplists:get_value(end_key_gt, Options, <<NS/binary, "0">>)
+ end,
+ case SK0 =< EK0 of
+ true ->
+ SK = select_gt(SK0, <<NS/binary, "/">>),
+ EK = select_lt(EK0, <<NS/binary, "0">>),
+ [{dir, proplists:get_value(dir, Options, fwd)},
+ {start_key, SK}, {EKType, EK}];
+ false ->
+ SK = select_lt(SK0, <<NS/binary, "0">>),
+ EK = select_gt(EK0, <<NS/binary, "/">>),
+ [{dir, proplists:get_value(dir, Options, fwd)},
+ {start_key, SK}, {EKType, EK}]
+ end.
select_gt(V1, V2) when V1 < V2 -> V2;
select_gt(V1, _V2) -> V1.
diff --git a/test/javascript/tests/design_docs_query.js b/test/javascript/tests/design_docs_query.js
new file mode 100644
index 000000000..8fc8da5f8
--- /dev/null
+++ b/test/javascript/tests/design_docs_query.js
@@ -0,0 +1,154 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.design_docs_query = function(debug) {
+ var db_name = get_random_db_name();
+ var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
+ db.createDb();
+ if (debug) debugger;
+
+ var docs = makeDocs(5);
+
+ // create the docs
+ var results = db.bulkSave(docs);
+ T(results.length == 5);
+ for (var i = 0; i < 5; i++) {
+ T(results[i].id == docs[i]._id);
+ }
+
+ // create the ddocs
+ for (var i = 0; i < 5; i++) {
+ T(db.save({
+ _id : "_design/ddoc0" + (i+1).toString(),
+ views : {
+ "testing" : {
+ "map" : "function(){emit(1,1)}"
+ }
+ }
+ }).ok);
+ }
+
+ // test design_docs
+ var path = "/" + db_name + "/_design_docs?";
+ var xhr_AllDDocs = CouchDB.request("GET", path);
+ T(xhr_AllDDocs.status == 200, "standard get should be 200");
+ var allDDocs = JSON.parse(xhr_AllDDocs.responseText);
+ TEquals(10, allDDocs.total_rows, "total_rows mismatch");
+ TEquals(5, allDDocs.rows.length, "amount of rows mismatch");
+
+ // test key="_design/ddoc03"
+ var xhr = CouchDB.request("GET", path + "key=\"_design/ddoc03\"");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(1, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc03", result.rows[0].key, "key test");
+
+ // test descending=true
+ var xhr = CouchDB.request("GET", path + "descending=true");
+ T(xhr.status == 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(5, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc05", result.rows[0].key, "descending test");
+
+ // test descending=false
+ var xhr = CouchDB.request("GET", path + "descending=false");
+ T(xhr.status == 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(5, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc01", result.rows[0].key, "descending test");
+
+ // test end_key="_design/ddoc03"
+ var xhr = CouchDB.request("GET", path + "end_key=\"_design/ddoc03\"");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(3, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc03", result.rows[2].key, "end_key test");
+
+ // test endkey="_design/ddoc03"
+ var xhr = CouchDB.request("GET", path + "endkey=\"_design/ddoc03\"");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(3, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc03", result.rows[2].key, "endkey test");
+
+ // test start_key="_design/ddoc03"
+ var xhr = CouchDB.request("GET", path + "start_key=\"_design/ddoc03\"");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(3, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc03", result.rows[0].key, "start_key test");
+
+ // test startkey="_design/ddoc03"
+ var xhr = CouchDB.request("GET", path + "startkey=\"_design/ddoc03\"");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(3, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc03", result.rows[0].key, "startkey test");
+
+ // test end_key="_design/ddoc03"&inclusive_end=true
+ var xhr = CouchDB.request("GET", path + "end_key=\"_design/ddoc03\"&inclusive_end=true");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(3, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc03", result.rows[2].key, "end_key and inclusive_end test");
+
+ // test end_key="_design/ddoc03"&inclusive_end=false
+ var xhr = CouchDB.request("GET", path + "end_key=\"_design/ddoc03\"&inclusive_end=false");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(2, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc02", result.rows[1].key, "end_key and inclusive_end test");
+
+ // test end_key="_design/ddoc03"&inclusive_end=false&descending=true
+ var xhr = CouchDB.request("GET", path +
+ "end_key=\"_design/ddoc03\"&inclusive_end=false&descending=true");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(2, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc04", result.rows[1].key, "end_key, inclusive_end and descending test");
+
+ // test end_key="_design/ddoc05"&limit=2
+ var xhr = CouchDB.request("GET", path +
+ "end_key=\"_design/ddoc05\"&limit=2");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(2, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc02", result.rows[1].key, "end_key and limit test");
+
+ // test end_key="_design/ddoc05"&skip=2
+ var xhr = CouchDB.request("GET", path +
+ "end_key=\"_design/ddoc05\"&skip=2");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(3, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc03", result.rows[0].key, "end_key and skip test");
+ TEquals("_design/ddoc05", result.rows[2].key, "end_key and skip test");
+
+ // test end_key="_design/ddoc05"&update_seq=true
+ var xhr = CouchDB.request("GET", path +
+ "end_key=\"_design/ddoc05\"&update_seq=true");
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ T(result.update_seq);
+
+ // test POST with keys
+ var xhr = CouchDB.request("POST", path, {
+ headers: {"Content-Type": "application/json"},
+ body: JSON.stringify({"keys" : ["_design/ddoc02", "_design/ddoc03"]})
+ });
+ T(xhr.status = 200, "standard get should be 200");
+ var result = JSON.parse(xhr.responseText);
+ TEquals(2, result.rows.length, "amount of rows mismatch");
+ TEquals("_design/ddoc03", result.rows[1].key, "POST test");
+
+ db.deleteDb();
+};