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