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()
 })