You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by gl...@apache.org on 2019/05/02 13:52:21 UTC
[couchdb-nano] branch master updated: Post search queries (#157)
This is an automated email from the ASF dual-hosted git repository.
glynnbird pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/couchdb-nano.git
The following commit(s) were added to refs/heads/master by this push:
new 51815f2 Post search queries (#157)
51815f2 is described below
commit 51815f25732f58094ae18d8ee605e7cf8740c7dd
Author: Sam Smith <sa...@linux.vnet.ibm.com>
AuthorDate: Thu May 2 14:52:17 2019 +0100
Post search queries (#157)
* Submit all search queries via POST.
* Expose `baseView` function.
---
lib/nano.d.ts | 7 ++
lib/nano.js | 51 +++-------
tests/fixtures/design/search.json | 33 -------
tests/intercept/design/search.js | 192 ++------------------------------------
4 files changed, 25 insertions(+), 258 deletions(-)
diff --git a/lib/nano.d.ts b/lib/nano.d.ts
index e02154e..e570772 100644
--- a/lib/nano.d.ts
+++ b/lib/nano.d.ts
@@ -234,6 +234,13 @@ declare namespace nano {
searchname: string,
params: DocumentSearchParams
): Request;
+ baseView<V>(
+ designname: string,
+ viewname: string,
+ meta: any,
+ params?: any,
+ callback?: Callback<any>
+ ): Promise<any>;
// http://docs.couchdb.org/en/latest/api/ddoc/views.html#get--db-_design-ddoc-_view-view
// http://docs.couchdb.org/en/latest/api/ddoc/views.html#post--db-_design-ddoc-_view-view
view<V>(
diff --git a/lib/nano.js b/lib/nano.js
index eb63555..d13b02d 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -624,46 +624,18 @@ module.exports = exports = function dbScope (cfg) {
// prevent mutation of the client qs object by using a clone
const qs1 = Object.assign({}, opts)
- const viewPath = '_design/' + ddoc + '/_' + meta.type + '/' + viewName
-
- // Several search parameters must be JSON-encoded; but since this is an
- // object API, several parameters need JSON endoding.
- const paramsToEncode = ['counts', 'group_sort', 'ranges', 'sort']
- paramsToEncode.forEach(function (param) {
- if (param in qs1) {
- if (typeof qs1[param] !== 'string') {
- qs1[param] = JSON.stringify(qs1[param])
- } else {
- // if the parameter is not already encoded, encode it
- try {
- JSON.parse(qs1[param])
- } catch (e) {
- qs1[param] = JSON.stringify(qs1[param])
- }
- }
- }
- })
+ const viewPath = meta.viewPath || '_design/' + ddoc + '/_' + meta.type +
+ '/' + viewName
- // the drilldown parameter needs special treatment. It can either be:
- // - a single array of strings e.g. ['author', 'Dickens']
- // - an array of arrays e.g. [['author','Dickens']['publisher','Penguin']]
- // The former should be JSON.stringified the latter should be an array of
- // JSON.stringified arrays(!).
- if (qs1['drilldown']) {
- // if this is an array of arrays
- if (Array.isArray(qs1['drilldown']) &&
- qs1['drilldown'].length > 0 &&
- Array.isArray(qs1['drilldown'][0])) {
- // JSON stringify each element of the array
- qs1['drilldown'] = qs1['drilldown'].map(function (val) {
- return JSON.stringify(val)
- })
- } else if (Array.isArray(qs1['drilldown'])) {
- qs1['drilldown'] = JSON.stringify(qs1['drilldown'])
- }
- }
-
- if (qs1 && qs1.keys) {
+ if (meta.type === 'search') {
+ return relax({
+ db: dbName,
+ path: viewPath,
+ method: 'POST',
+ body: qs1,
+ stream: meta.stream
+ }, callback)
+ } else if (qs1 && qs1.keys) {
const body = {keys: qs1.keys}
delete qs1.keys
return relax({
@@ -947,6 +919,7 @@ module.exports = exports = function dbScope (cfg) {
show: showDoc,
atomic: updateWithHandler,
updateWithHandler: updateWithHandler,
+ baseView: view,
search: viewSearch,
searchAsStream: viewSearchAsStream,
view: viewDocs,
diff --git a/tests/fixtures/design/search.json b/tests/fixtures/design/search.json
index 88a25c5..8a5451c 100644
--- a/tests/fixtures/design/search.json
+++ b/tests/fixtures/design/search.json
@@ -4,39 +4,6 @@
, "status" : 201
, "response" : "{ \"ok\": true }"
}
-, { "method" : "put"
- , "path" : "/design_search/_design/people/_search"
- , "body" : "*"
- , "status" : 201
- , "response" : "{\"ok\":true,\"id\":\"_design/people/_search\",\"rev\":\"1-14e6bc\"}"
- }
-, { "method" : "put"
- , "status" : 201
- , "path" : "/design_search/p_derek"
- , "body" : "*"
- , "response" : "{\"ok\":true,\"id\":\"p_derek\",\"rev\":\"1-4c6114\"}"
- }
-, { "method" : "put"
- , "status" : 201
- , "path" : "/design_search/p_randall"
- , "body" : "*"
- , "response" : "{\"ok\":true,\"id\":\"p_randall\",\"rev\":\"1-4c6114\"}"
- }
-, { "method" : "put"
- , "status" : 201
- , "path" : "/design_search/p_nuno"
- , "body" : "*"
- , "response" : "{\"ok\":true,\"id\":\"p_nuno\",\"rev\":\"1-4c6114\"}"
- }
-, { "path" : "/design_search/_design/people/_search/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D"
- , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n"
- }
-, { "path" : "/design_search/_design/people/_search/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D"
- , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n"
- }
-, { "path" : "/design_search/_design/people/_search/by_name_and_city?key=%5B%22Derek%22%2C%22San%20Francisco%22%5D"
- , "response" : "{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"p_derek\",\"key\":[\"Derek\",\"San Francisco\"],\"value\":\"p_derek\"}\r\n]}\n"
- }
, { "method" : "delete"
, "path" : "/design_search"
, "status" : 200
diff --git a/tests/intercept/design/search.js b/tests/intercept/design/search.js
index 6079903..8de79a9 100644
--- a/tests/intercept/design/search.js
+++ b/tests/intercept/design/search.js
@@ -42,192 +42,14 @@ it('should allow custom request object to be supplied', function (assert) {
})
})
-it('should encode array counts parameter', function (assert) {
- const p = db.search('fake', 'fake', { counts: ['brand', 'colour'] })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should not encode string counts parameter', function (assert) {
- const p = db.search('fake', 'fake',
- { counts: JSON.stringify(['brand', 'colour']) })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should encode array drilldown parameter', function (assert) {
- const p = db.search('fake', 'fake', { drilldown: ['colour', 'red'] })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should not encode string drilldown parameter', function (assert) {
- const p = db.search('fake', 'fake',
- { drilldown: JSON.stringify(['colour', 'red']) })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should encode array of arrays drilldown parameter', function (assert) {
+it('should submit all search queries via a POST request', function (assert) {
const p = db.search('fake', 'fake', { drilldown: [['colour', 'red'], ['category', 'cake']] })
assert.ok(helpers.isPromise(p), 'returns Promise')
p.then(function (data) {
assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- console.log(data.headers)
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should encode array group_sort parameter', function (assert) {
- const p = db.search('fake', 'fake',
- { group_sort: ['-foo<number>', 'bar<string>'] })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should not encode string group_sort parameter', function (assert) {
- const p = db.search('fake', 'fake',
- { group_sort: JSON.stringify(['-foo<number>', 'bar<string>']) })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should encode object ranges parameter', function (assert) {
- const p = db.search('fake', 'fake',
- { ranges: {'price': '[0 TO 10]'} })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should not encode string ranges parameter', function (assert) {
- const p = db.search('fake', 'fake',
- { ranges: JSON.stringify({'price': '[0 TO 10]'}) })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should encode array sort parameter', function (assert) {
- const p = db.search('fake', 'fake',
- { sort: ['-foo<number>', 'bar<string>'] })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should not encode string sort parameter', function (assert) {
- const p = db.search('fake', 'fake',
- { sort: JSON.stringify(['-foo<number>', 'bar<string>']) })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should encode unencoded sort parameter', function (assert) {
- const p = db.search('fake', 'fake',
- { sort: '-foo<number>' })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
- assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
- assert.end()
- }).catch(function () {
- assert.ok(true, 'Promise is rejected')
- })
-})
-
-it('should not encode encoded string sort parameter', function (assert) {
- const p = db.search('fake', 'fake',
- { sort: JSON.stringify('-foo<number>') })
- assert.ok(helpers.isPromise(p), 'returns Promise')
- p.then(function (data) {
- assert.ok(true, 'Promise is resolved')
- assert.equal(data.method, 'GET')
+ assert.equal(data.method, 'POST')
assert.equal(typeof data.headers, 'object')
- assert.equal(typeof data.qs, 'object')
+ assert.equal(data.body, '{"drilldown":[["colour","red"],["category","cake"]]}')
assert.end()
}).catch(function () {
assert.ok(true, 'Promise is rejected')
@@ -235,11 +57,9 @@ it('should not encode encoded string sort parameter', function (assert) {
})
it('should allow search results to be streamed', function (assert) {
- const req = db.searchAsStream('fake', 'fake',
- { q: 'foo:bar' })
- assert.equal(req.method, 'GET')
+ const req = db.searchAsStream('fake', 'fake', { q: 'foo:bar' })
+ assert.equal(req.method, 'POST')
assert.equal(typeof req.headers, 'object')
- assert.equal(typeof req.qs, 'object')
- assert.equal(req.qs.q, 'foo:bar')
+ assert.equal(req.body, '{"q":"foo:bar"}')
assert.end()
})