Skip to content

Commit

Permalink
Merge pull request #105 from Fonger/read-concern
Browse files Browse the repository at this point in the history
Add readConcern and collation support
  • Loading branch information
vkarpov15 authored Jul 29, 2018
2 parents 7ba9ac7 + 7d9fd55 commit b19860a
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 4 deletions.
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,17 @@ require('mongodb').connect(uri, function (err, db) {
- [where](#where)
- [$where](#where-1)
- [batchSize](#batchsize)
- [collation](#collation)
- [comment](#comment)
- [hint](#hint)
- [limit](#limit)
- [maxScan](#maxscan)
- [maxTime](#maxtime)
- [maxTimeMS](#maxtime)
- [skip](#skip)
- [sort](#sort)
- [read](#read)
- [readConcern](#readconcern)
- [slaveOk](#slaveok)
- [snapshot](#snapshot)
- [tailable](#tailable)
Expand Down Expand Up @@ -821,6 +824,16 @@ _Cannot be used with `distinct()`._
[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.batchSize/)
### collation()
Specifies the collation option.
```js
query.collation({ locale: "en_US", strength: 1 })
```
[MongoDB documentation](https://docs.mongodb.com/manual/reference/method/cursor.collation/#cursor.collation)
### comment()
Specifies the comment option.
Expand Down Expand Up @@ -875,6 +888,7 @@ Specifies the maxTimeMS option.
```js
query.maxTime(100)
query.maxTimeMS(100)
```
[MongoDB documentation](http://docs.mongodb.org/manual/reference/method/cursor.maxTimeMS/)
Expand Down Expand Up @@ -964,6 +978,46 @@ mquery(..).read(preference).exec();
Read more about how to use read preferences [here](http://docs.mongodb.org/manual/applications/replication/#read-preference) and [here](http://mongodb.github.com/node-mongodb-native/driver-articles/anintroductionto1_1and2_2.html#read-preferences).
### readConcern()
Sets the readConcern option for the query.
```js
mquery().readConcern('local')
mquery().readConcern('l') // same as local

mquery().readConcern('available')
mquery().readConcern('a') // same as available

mquery().readConcern('majority')
mquery().readConcern('m') // same as majority

mquery().readConcern('linearizable')
mquery().readConcern('lz') // same as linearizable

mquery().readConcern('snapshot')
mquery().readConcern('s') // same as snapshot
```
##### Read Concern Level:
- `local` - The query returns from the instance with no guarantee guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back). (MongoDB 3.2+)
- `available` - The query returns from the instance with no guarantee guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back). (MongoDB 3.6+)
- `majority` - The query returns the data that has been acknowledged by a majority of the replica set members. The documents returned by the read operation are durable, even in the event of failure. (MongoDB 3.2+)
- `linearizable` - Read from a secondary if available, otherwise read from the primary. (MongoDB 3.4+)
- `snapshot` - The query returns data that reflects all successful majority-acknowledged writes that completed prior to the start of the read operation. The query may wait for concurrently executing writes to propagate to a majority of replica set members before returning results. (MongoDB 4.0+)
Aliases
- `l` local
- `a` available
- `m` majority
- `lz` linearizable
- `s` snapshot
Read more about how to use read concern [here](https://docs.mongodb.com/manual/reference/read-concern/).
### slaveOk()
Sets the slaveOk option. `true` allows reading from secondaries.
Expand Down
72 changes: 71 additions & 1 deletion lib/mquery.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,24 @@ Query.prototype.collection = function collection (coll) {
return this;
}

/**
* Adds a collation to this op (MongoDB 3.4 and up)
*
* ####Example
*
* query.find().collation({ locale: "en_US", strength: 1 })
*
* @param {Object} value
* @return {Query} this
* @see MongoDB docs https://docs.mongodb.com/manual/reference/method/cursor.collation/#cursor.collation
* @api public
*/

Query.prototype.collation = function(value) {
this.options.collation = value;
return this;
};

/**
* Specifies a `$where` condition
*
Expand Down Expand Up @@ -1447,6 +1465,7 @@ function _pushMap (opts, map) {
* ####Example
*
* query.maxTime(100)
* query.maxTimeMS(100)
*
* @method maxTime
* @memberOf Query
Expand All @@ -1455,7 +1474,7 @@ function _pushMap (opts, map) {
* @api public
*/

Query.prototype.maxTime = function (v) {
Query.prototype.maxTime = Query.prototype.maxTimeMS = function (v) {
this._validate('maxTime');
this.options.maxTimeMS = v;
return this;
Expand Down Expand Up @@ -1610,6 +1629,57 @@ Query.prototype.read = function (pref) {
return this;
}

/**
* Sets the readConcern option for the query.
*
* ####Example:
*
* new Query().readConcern('local')
* new Query().readConcern('l') // same as local
*
* new Query().readConcern('available')
* new Query().readConcern('a') // same as available
*
* new Query().readConcern('majority')
* new Query().readConcern('m') // same as majority
*
* new Query().readConcern('linearizable')
* new Query().readConcern('lz') // same as linearizable
*
* new Query().readConcern('snapshot')
* new Query().readConcern('s') // same as snapshot
*
*
* ####Read Concern Level:
*
* local MongoDB 3.2+ The query returns from the instance with no guarantee guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back).
* available MongoDB 3.6+ The query returns from the instance with no guarantee guarantee that the data has been written to a majority of the replica set members (i.e. may be rolled back).
* majority MongoDB 3.2+ The query returns the data that has been acknowledged by a majority of the replica set members. The documents returned by the read operation are durable, even in the event of failure.
* linearizable MongoDB 3.4+ Read from a secondary if available, otherwise read from the primary.
* snapshot MongoDB 4.0+ The query returns data that reflects all successful majority-acknowledged writes that completed prior to the start of the read operation. The query may wait for concurrently executing writes to propagate to a majority of replica set members before returning results.
*
*
* Aliases
*
* l local
* a available
* m majority
* lz linearizable
* s snapshot
*
* Read more about how to use read concern [here](https://docs.mongodb.com/manual/reference/read-concern/).
*
* @param {String} level one of the listed read concern level or their aliases
* @see mongodb https://docs.mongodb.com/manual/reference/read-concern/
* @return {Query} this
* @api public
*/

Query.prototype.readConcern = function (level) {
this.options.readConcern = utils.readConcern(level)
return this
}

/**
* Sets tailable option.
*
Expand Down
41 changes: 40 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,45 @@ exports.readPref = function readPref (pref) {
return pref;
}


/**
* Read Concern helper (mongo 3.2 drivers support this)
*
* Allows using string to specify read concern level:
*
* local 3.2+
* available 3.6+
* majority 3.2+
* linearizable 3.4+
* snapshot 4.0+
*
* @param {String} readConcern
*/

exports.readConcern = function readConcern (concern) {
if ('string' === typeof concern) {
switch (concern) {
case 'l':
concern = 'local'
break;
case 'a':
concern = 'available';
break;
case 'm':
concern = 'majority';
break;
case 'lz':
concern = 'linearizable';
break;
case 's':
concern = 'snapshot';
break;
}
concern = { level: concern }
}
return concern
}

/**
* Object.prototype.toString.call helper
*/
Expand Down Expand Up @@ -303,7 +342,7 @@ var soon = exports.soon = 'function' == typeof setImmediate
*/

exports.cloneBuffer = function (buff) {
var dupe = new Buffer(buff.length);
var dupe = Buffer.alloc(buff.length);
buff.copy(dupe, 0, 0, buff.length);
return dupe;
};
Expand Down
46 changes: 46 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1304,6 +1304,18 @@ describe('mquery', function(){
})
})

describe('readConcern', function(){
it('sets associated readConcern option', function(){
var m = mquery();
m.readConcern('s');
assert.deepEqual({ level: 'snapshot' }, m.options.readConcern);
})
it('is chainable', function(){
var m = mquery();
assert.equal(m, m.readConcern('lz'));
})
})

describe('tailable', function(){
it('works', function(){
var query = mquery();
Expand Down Expand Up @@ -2522,6 +2534,40 @@ describe('mquery', function(){
done();
})
})

it('works with readConcern', function (done) {
var m = mquery(col).find({ name: 'exec' });
try {
m.readConcern('l');
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND')
e = null;
done(e);
return;
}
m.exec(function (err, docs) {
assert.ifError(err);
assert.equal(2, docs.length);
done();
})
})

it('works with collation', function (done) {
var m = mquery(col).find({ name: 'EXEC' });
try {
m.collation({ locale: "en_US", strength: 1 })
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND')
e = null;
done(e);
return;
}
m.exec(function (err, docs) {
assert.ifError(err);
assert.equal(2, docs.length);
done();
})
})
});

it('findOne', function(done){
Expand Down
4 changes: 2 additions & 2 deletions test/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ describe('lib/utils', function() {
it('clones mongodb.Binary', function(done){
if (!mongo) return done();

var buf = new Buffer('hi');
var buf = Buffer.from('hi');
var binary= new mongo.Binary(buf, 2);
var clone = utils.clone(binary);
assert.equal(binary.sub_type, clone.sub_type);
Expand All @@ -129,7 +129,7 @@ describe('lib/utils', function() {
});

it('handles buffers', function(done){
var buff = new Buffer(10);
var buff = Buffer.alloc(10);
buff.fill(1);
var clone = utils.clone(buff);

Expand Down

0 comments on commit b19860a

Please sign in to comment.