Ability to get a cursor from a findOne

pull/2/head
Louis Chatriot 11 years ago
parent e050dcac23
commit 905a520e0a
  1. 10
      lib/cursor.js
  2. 23
      lib/datastore.js
  3. 2
      test/cursor.test.js
  4. 37
      test/db.test.js

@ -9,10 +9,12 @@ var model = require('./model');
* Create a new cursor for this collection
* @param {Datastore} db - The datastore this cursor is bound to
* @param {Query} query - The query this cursor will operate on
* @param {Function} execDn - Handler to be executed after cursor has found the results and before the callback passed to find/findOne/update/remove
*/
function Cursor (db, query) {
function Cursor (db, query, execFn) {
this.db = db;
this.query = query || {};
if (execFn) { this.execFn = execFn; }
}
@ -96,7 +98,11 @@ Cursor.prototype._exec = function(callback) {
res = res.slice(skip, skip + limit);
}
return callback(null, res);
if (this.execFn) {
return this.execFn(null, res, callback);
} else {
return callback(null, res);
}
};
Cursor.prototype.exec = function () {

@ -389,7 +389,10 @@ Datastore.prototype.count = function() {
* @param {Object} query MongoDB-style query
*/
Datastore.prototype.find = function (query, callback) {
var cursor = new Cursor(this, query);
var cursor = new Cursor(this, query, function(err, docs, callback) {
if (err) { return callback(err); }
return callback(null, docs);
});
if (typeof callback === 'function') {
cursor.exec(callback);
@ -404,15 +407,21 @@ Datastore.prototype.find = function (query, callback) {
* @param {Object} query MongoDB-style query
*/
Datastore.prototype.findOne = function (query, callback) {
var cursor = new Cursor(this, query);
cursor.limit(1);
cursor.exec(function (err, docs) {
if (err) {
return callback(err);
var cursor = new Cursor(this, query, function(err, docs, callback) {
if (err) { return callback(err); }
if (docs.length === 1) {
return callback(null, docs[0]);
} else {
return callback(null, docs.length === 1 ? docs[0] : null);
return callback(null, null);
}
});
cursor.limit(1);
if (typeof callback === 'function') {
cursor.exec(callback);
} else {
return cursor;
}
};

@ -531,7 +531,7 @@ describe('Cursor', function () {
}
], done);
});
it('Multiple consecutive sorts', function(done) {
async.waterfall([
function (cb) {

@ -620,7 +620,42 @@ describe('Database', function () {
});
});
});
it('Can use sort and skip if the callback is not passed to findOne but to exec', function (done) {
d.insert({ a: 2, hello: 'world' }, function () {
d.insert({ a: 24, hello: 'earth' }, function () {
d.insert({ a: 13, hello: 'blueplanet' }, function () {
d.insert({ a: 15, hello: 'home' }, function () {
// No skip no query
d.findOne({}).sort({ a: 1 }).exec(function (err, doc) {
assert.isNull(err);
doc.hello.should.equal('world');
// A query
d.findOne({ a: { $gt: 14 } }).sort({ a: 1 }).exec(function (err, doc) {
assert.isNull(err);
doc.hello.should.equal('home');
// And a skip
d.findOne({ a: { $gt: 14 } }).sort({ a: 1 }).skip(1).exec(function (err, doc) {
assert.isNull(err);
doc.hello.should.equal('earth');
// No result
d.findOne({ a: { $gt: 14 } }).sort({ a: 1 }).skip(2).exec(function (err, doc) {
assert.isNull(err);
assert.isNull(doc);
done();
});
});
});
});
});
});
});
});
});
}); // ==== End of 'Find' ==== //

Loading…
Cancel
Save