added Datastore.count with documentation and tests

pull/2/head
Antti Saarinen 11 years ago
parent c552e37772
commit b0bbf86e6d
  1. 13
      README.md
  2. 29
      lib/datastore.js
  3. 84
      test/db.test.js

@ -164,6 +164,19 @@ db.findOne({ _id: 'id1' }, function (err, doc) {
}); });
``` ```
#### Counting objects
Similar to `find`, you can count the number of matching documents by calling `count`. For example
```javascript
// Using same datastore as above
// Count all planets in the solar system
db.count({ system: 'solar' }, function (err, count) {
// count equals to 3
// If no document is found, count is 0
});
```
#### Operators ($lt, $lte, $gt, $gte, $in, $nin, $ne, $exists, $regex) #### Operators ($lt, $lte, $gt, $gte, $in, $nin, $ne, $exists, $regex)
The syntax is `{ field: { $op: value } }` where `$op` is any comparison operator: The syntax is `{ field: { $op: value } }` where `$op` is any comparison operator:

@ -272,6 +272,35 @@ Datastore.prototype.insert = function () {
this.executor.push({ this: this, fn: this._insert, arguments: arguments }); this.executor.push({ this: this, fn: this._insert, arguments: arguments });
}; };
/**
* Count all documents matching the query
* @param {Object} query MongoDB-style query
*
* @api private Use count
*/
Datastore.prototype._count = function(query, callback) {
var res = 0
, self = this
, candidates = this.getCandidates(query)
, i
;
try {
for (i = 0; i < candidates.length; i += 1) {
if (model.match(candidates[i], query)) {
res++;
}
}
} catch (err) {
return callback(err);
}
return callback(null, res);
}
Datastore.prototype.count = function() {
this.executor.push({this: this, fn: this._count, arguments: arguments });
}
/** /**
* Find all documents matching the query * Find all documents matching the query

@ -484,6 +484,90 @@ describe('Database', function () {
}); // ==== End of 'Find' ==== // }); // ==== End of 'Find' ==== //
describe('Count', function() {
it('Count all documents if an empty query is used', function (done) {
async.waterfall([
function (cb) {
d.insert({ somedata: 'ok' }, function (err) {
d.insert({ somedata: 'another', plus: 'additional data' }, function (err) {
d.insert({ somedata: 'again' }, function (err) { return cb(err); });
});
});
}
, function (cb) { // Test with empty object
d.count({}, function (err, docs) {
assert.isNull(err);
docs.should.equal(3);
return cb();
});
}
], done);
});
it('Count all documents matching a basic query', function (done) {
async.waterfall([
function (cb) {
d.insert({ somedata: 'ok' }, function (err) {
d.insert({ somedata: 'again', plus: 'additional data' }, function (err) {
d.insert({ somedata: 'again' }, function (err) { return cb(err); });
});
});
}
, function (cb) { // Test with query that will return docs
d.count({ somedata: 'again' }, function (err, docs) {
assert.isNull(err);
docs.should.equal(2);
return cb();
});
}
, function (cb) { // Test with query that doesn't match anything
d.count({ somedata: 'nope' }, function (err, docs) {
assert.isNull(err);
docs.should.equal(0);
return cb();
});
}
], done);
});
it('Array fields match if any element matches', function (done) {
d.insert({ fruits: ['pear', 'apple', 'banana'] }, function (err, doc1) {
d.insert({ fruits: ['coconut', 'orange', 'pear'] }, function (err, doc2) {
d.insert({ fruits: ['banana'] }, function (err, doc3) {
d.count({ fruits: 'pear' }, function (err, docs) {
assert.isNull(err);
docs.should.equal(2);
d.count({ fruits: 'banana' }, function (err, docs) {
assert.isNull(err);
docs.should.equal(2);
d.count({ fruits: 'doesntexist' }, function (err, docs) {
assert.isNull(err);
docs.should.equal(0);
done();
});
});
});
});
});
});
});
it('Returns an error if the query is not well formed', function (done) {
d.insert({ hello: 'world' }, function () {
d.count({ $or: { hello: 'world' } }, function (err, docs) {
assert.isDefined(err);
assert.isUndefined(docs);
done();
});
});
});
});
describe('Update', function () { describe('Update', function () {

Loading…
Cancel
Save