You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2017/01/17 14:16:53 UTC

couchdb-nano git commit: Nano improvements

Repository: couchdb-nano
Updated Branches:
  refs/heads/master 4e38f2244 -> 29bc8031b


Nano improvements

The improvements:
* Node 0.12 is no longer supported
* Only JSON encode parameters which are not strings to avoid double encoding as per https://github.com/cloudant/nodejs-cloudant/issues/89
* Update package.json for this repo's project name
* Added GET /_uuids api call
* Added selective encoding of string parameters to the search function


Project: http://git-wip-us.apache.org/repos/asf/couchdb-nano/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-nano/commit/29bc8031
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-nano/tree/29bc8031
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-nano/diff/29bc8031

Branch: refs/heads/master
Commit: 29bc8031b709d0e2fc8d573cfea6f617f5c22d35
Parents: 4e38f22
Author: Glynn Bird <gl...@gmail.com>
Authored: Thu Nov 3 15:35:53 2016 +0000
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Jan 17 16:16:40 2017 +0200

----------------------------------------------------------------------
 .travis.yml                      |   3 -
 README.md                        |  16 ++++
 lib/nano.js                      |  24 ++++-
 package.json                     |   4 +-
 tests/fixtures/util/uuid.json    |  12 +++
 tests/integration/util/uuid.js   |  39 ++++++++
 tests/intercept/design/search.js | 170 ++++++++++++++++++++++++++++++++++
 7 files changed, 261 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-nano/blob/29bc8031/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index 0e7bd2c..c170be9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,9 +6,6 @@ branches:
     - next
     - rewrite
 node_js:
-  - "0.8"
-  - "0.10"
-  - "0.11"
   - "0.12"
   - "iojs"
   - "4.2"

http://git-wip-us.apache.org/repos/asf/couchdb-nano/blob/29bc8031/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 3bfbe57..af69a68 100644
--- a/README.md
+++ b/README.md
@@ -61,6 +61,7 @@ minimalistic couchdb driver for node.js
   - [db.search(designname, viewname, [params], [callback])](#dbsearchdesignname-searchname-params-callback)
 - [using cookie authentication](#using-cookie-authentication)
 - [advanced features](#advanced-features)
+  - [getting uuids](#getting-uuids)
   - [extending nano](#extending-nano)
   - [pipes](#pipes)
 - [tests](#tests)
@@ -776,6 +777,21 @@ nano.session(function(err, session) {
 
 ## advanced features
 
+### getting uuids
+
+if your application needs to generate UUIDs, then CouchDB can provide some for you
+
+```js
+nano.uuids(3, callback);
+// { uuid: [
+// '5d1b3ef2bc7eea51f660c091e3dffa23',
+// '5d1b3ef2bc7eea51f660c091e3e006ff',
+// '5d1b3ef2bc7eea51f660c091e3e007f0',
+//]}
+```
+
+The first parameter is the number of uuids to generate. If omitted, it defaults to 1.
+
 ### extending nano
 
 nano is minimalistic but you can add your own features with

http://git-wip-us.apache.org/repos/asf/couchdb-nano/blob/29bc8031/lib/nano.js
----------------------------------------------------------------------
diff --git a/lib/nano.js b/lib/nano.js
index b9223ba..8789fa0 100644
--- a/lib/nano.js
+++ b/lib/nano.js
@@ -360,6 +360,16 @@ module.exports = exports = nano = function dbScope(cfg) {
     return relax({db: '_replicate', body: opts, method: 'POST'}, callback);
   }
 
+  // http://docs.couchdb.org/en/latest/api/server/common.html#uuids
+  function uuids(count, callback) {
+    if (typeof count === 'function') {
+      callback = count;
+      count = 1;
+    }
+
+    return relax({ method: 'GET', path: '_uuids', qs: {count: count}}, callback);
+  }
+
   function docModule(dbName) {
     var docScope = {};
     dbName = decodeURIComponent(dbName);
@@ -512,7 +522,16 @@ module.exports = exports = nano = function dbScope(cfg) {
       var paramsToEncode = ['counts', 'drilldown', 'group_sort', 'ranges', 'sort'];
       paramsToEncode.forEach(function(param) {
         if (param in qs) {
-          qs[param] = JSON.stringify(qs[param]);
+          if (typeof qs[param] !== 'string') {
+            qs[param] = JSON.stringify(qs[param]);
+          } else {
+            // if the parameter is not already encoded, encode it
+            try {
+              JSON.parse(qs[param]);
+            } catch(e) {
+              qs[param] = JSON.stringify(qs[param]);
+            }
+          }
         }
       });
 
@@ -776,7 +795,8 @@ module.exports = exports = nano = function dbScope(cfg) {
     auth: auth,
     session: session,
     updates: updates,
-    followUpdates: followUpdates
+    followUpdates: followUpdates,
+    uuids: uuids
   });
 
   var db = maybeExtractDatabaseComponent();

http://git-wip-us.apache.org/repos/asf/couchdb-nano/blob/29bc8031/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 9f8fdfe..2a30174 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
   "description": "The official CouchDB client for Node.js",
   "license": "Apache-2.0",
   "homepage": "http://github.com/apache/couchdb-nano",
-  "repository": "git://github.com/apache/couchdb-nano",
+  "repository": "http://github.com/apache/couchdb-nano",
   "version": "6.2.0",
   "author": "Apache CouchDB <de...@couchdb.apache.org> (http://couchdb.apache.org)",
   "keywords": [
@@ -45,7 +45,7 @@
   },
   "main": "./lib/nano.js",
   "engines": {
-    "node": ">=0.8.0"
+    "node": ">=0.12"
   },
   "pre-commit": [
     "jshint",

http://git-wip-us.apache.org/repos/asf/couchdb-nano/blob/29bc8031/tests/fixtures/util/uuid.json
----------------------------------------------------------------------
diff --git a/tests/fixtures/util/uuid.json b/tests/fixtures/util/uuid.json
new file mode 100644
index 0000000..b14ccc5
--- /dev/null
+++ b/tests/fixtures/util/uuid.json
@@ -0,0 +1,12 @@
+[
+  { "method"   : "get"
+  , "path"     : "/uuids?count=3"
+  , "status"   : 200
+  , "response" : "{ \"uuids\": [\"1\",\"2\",\"3\"] }"
+  }
+, { "method"   : "get"
+  , "path"     : "/uuids"
+  , "status"   : 200
+  , "response" : "{ \"uuids\": [\"1\"] }"
+  }
+]

http://git-wip-us.apache.org/repos/asf/couchdb-nano/blob/29bc8031/tests/integration/util/uuid.js
----------------------------------------------------------------------
diff --git a/tests/integration/util/uuid.js b/tests/integration/util/uuid.js
new file mode 100644
index 0000000..2faed02
--- /dev/null
+++ b/tests/integration/util/uuid.js
@@ -0,0 +1,39 @@
+// 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.
+
+'use strict';
+
+var helpers = require('../../helpers/integration');
+var harness = helpers.harness(__filename);
+var db = harness.locals.db;
+var nano = helpers.nano;
+var it = harness.it;
+
+it('should insert a one item', helpers.insertOne);
+
+it('should generate three uuids', function(assert) {
+  nano.uuids(3, function(error, data) {
+    assert.equal(error, null, 'should generate uuids');
+    assert.ok(data.uuids, 'got uuids');
+    assert.equal(data.uuids.count, 3, 'got 3');
+    assert.end();
+  });
+});
+
+it('should generate one uuid', function(assert) {
+  nano.uuids(function(error, data) {
+    assert.equal(error, null, 'should generate uuids');
+    assert.ok(data.uuids, 'got uuids');
+    assert.equal(data.uuids.count, 1, 'got 1');
+    assert.end();
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb-nano/blob/29bc8031/tests/intercept/design/search.js
----------------------------------------------------------------------
diff --git a/tests/intercept/design/search.js b/tests/intercept/design/search.js
new file mode 100644
index 0000000..c6f8352
--- /dev/null
+++ b/tests/intercept/design/search.js
@@ -0,0 +1,170 @@
+// 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.
+
+'use strict';
+
+var helpers = require('../../helpers/integration');
+var harness = helpers.harness(__filename);
+var it = harness.it;
+
+var nano = require('../../../lib/nano.js');
+var fakeRequest = function(r, callback) {
+  callback(null, { statusCode: 200 }, r);
+};
+// by passing in a fake Request object, we can intercept the request
+// and see how Nano is pre-processing the parameters
+var n = nano({url: 'http://localhost:5984', request: fakeRequest});
+var db = n.db.use('fake');
+
+it('should allow custom request object to be supplied', function(assert) {
+  db.info(function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.end();
+  });
+});
+
+it('should encode array counts parameter', function(assert) {
+  db.search('fake', 'fake', { counts: ['brand','colour'] }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.counts, JSON.stringify(['brand','colour']));
+      assert.end();
+  });
+});
+
+it('should not encode string counts parameter', function(assert) {
+  db.search('fake', 'fake', { counts: JSON.stringify(['brand','colour']) }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.counts, JSON.stringify(['brand','colour']));
+      assert.end();
+  });
+});
+
+it('should encode array drilldown parameter', function(assert) {
+  db.search('fake', 'fake', { drilldown: ['colour','red'] }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.drilldown, JSON.stringify(['colour','red']));
+      assert.end();
+  });
+});
+
+it('should not encode string drilldown parameter', function(assert) {
+  db.search('fake', 'fake', { drilldown: JSON.stringify(['colour','red']) }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.drilldown, JSON.stringify(['colour','red']));
+      assert.end();
+  });
+});
+
+it('should encode array group_sort parameter', function(assert) {
+  db.search('fake', 'fake', { group_sort: ['-foo<number>','bar<string>'] }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.group_sort, JSON.stringify(['-foo<number>','bar<string>']));
+      assert.end();
+  });
+});
+
+it('should not encode string group_sort parameter', function(assert) {
+  db.search('fake', 'fake', { group_sort: JSON.stringify(['-foo<number>','bar<string>']) }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.group_sort, JSON.stringify(['-foo<number>','bar<string>']));
+      assert.end();
+  });
+});
+
+it('should encode object ranges parameter', function(assert) {
+  db.search('fake', 'fake', { ranges: {'price':'[0 TO 10]'} }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.ranges, JSON.stringify({'price':'[0 TO 10]'}));
+      assert.end();
+  });
+});
+
+it('should not encode string ranges parameter', function(assert) {
+  db.search('fake', 'fake', { ranges: JSON.stringify({'price':'[0 TO 10]'}) }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.ranges, JSON.stringify({'price':'[0 TO 10]'}));
+      assert.end();
+  });
+});
+
+it('should encode array sort parameter', function(assert) {
+  db.search('fake', 'fake', { sort: ['-foo<number>','bar<string>'] }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.sort, JSON.stringify(['-foo<number>','bar<string>']));
+      assert.end();
+  });
+});
+
+it('should not encode string sort parameter', function(assert) {
+  db.search('fake', 'fake', { sort: JSON.stringify(['-foo<number>','bar<string>']) }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.sort, JSON.stringify(['-foo<number>','bar<string>']));
+      assert.end();
+  });
+});
+
+it('should encode unencoded sort parameter', function(assert) {
+  db.search('fake', 'fake', { sort: '-foo<number>' }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.sort, JSON.stringify('-foo<number>'));
+      assert.end();
+  });
+});
+
+it('should not encode encoded string sort parameter', function(assert) {
+  db.search('fake', 'fake', { sort: JSON.stringify('-foo<number>') }, function(err, data) {
+      assert.equal(err, null);
+      assert.equal(data.method, 'GET');
+      assert.equal(typeof data.headers, 'object');
+      assert.equal(typeof data.qs, 'object');
+      assert.equal(data.qs.sort, JSON.stringify('-foo<number>'));
+      assert.end();
+  });
+});
+
+
+console.log('I AM HERE');
\ No newline at end of file