From e050dcac231a6255dc44f9de8f1833a36502a526 Mon Sep 17 00:00:00 2001 From: Louis Chatriot Date: Sun, 26 Jan 2014 13:12:56 +0100 Subject: [PATCH] Multiple consecutive sorts are handled --- lib/cursor.js | 12 +++++--- lib/datastore.js | 12 -------- test/cursor.test.js | 75 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 80 insertions(+), 19 deletions(-) diff --git a/lib/cursor.js b/lib/cursor.js index 67cd821..cc632bf 100644 --- a/lib/cursor.js +++ b/lib/cursor.js @@ -53,7 +53,7 @@ Cursor.prototype.sort = function(sortQuery) { Cursor.prototype._exec = function(callback) { var candidates = this.db.getCandidates(this.query) , res = [], added = 0, skipped = 0, self = this - , i + , i, keys, key ; try { @@ -79,11 +79,15 @@ Cursor.prototype._exec = function(callback) { // Apply all sorts if (this._sort) { - Object.keys(this._sort).forEach(function(key) { + keys = Object.keys(this._sort); + + // Going backwards so that the first sort is the last that gets applied + for (i = keys.length - 1; i >= 0; i -= 1) { + key = keys[i]; res.sort(function(a, b) { return self._sort[key] * model.compareThings(model.getDotValue(a, key), model.getDotValue(b, key)); - }); - }); + }); + } // Applying limit and skip var limit = this._limit || res.length diff --git a/lib/datastore.js b/lib/datastore.js index 8377a47..df7e058 100644 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -387,8 +387,6 @@ Datastore.prototype.count = function() { * Find all documents matching the query * If no callback is passed, we return the cursor so that user can limit, skip and finally exec * @param {Object} query MongoDB-style query - * - * @api private Use find */ Datastore.prototype.find = function (query, callback) { var cursor = new Cursor(this, query); @@ -400,16 +398,10 @@ Datastore.prototype.find = function (query, callback) { } }; -// Datastore.prototype.find = function () { - // this.executor.push({ this: this, fn: this._find, arguments: arguments }); -// }; - /** * Find one document matching the query * @param {Object} query MongoDB-style query - * - * @api private Use findOne */ Datastore.prototype.findOne = function (query, callback) { var cursor = new Cursor(this, query); @@ -423,10 +415,6 @@ Datastore.prototype.findOne = function (query, callback) { }); }; -// Datastore.prototype.findOne = function () { - // this.executor.push({ this: this, fn: this._findOne, arguments: arguments }); -// }; - /** * Update all docs matching query diff --git a/test/cursor.test.js b/test/cursor.test.js index 10191ba..f354ad3 100644 --- a/test/cursor.test.js +++ b/test/cursor.test.js @@ -532,9 +532,78 @@ describe('Cursor', function () { ], done); }); - it.skip('Multiple consecutive sorts', function(done) { - done(); - }); + it('Multiple consecutive sorts', function(done) { + async.waterfall([ + function (cb) { + d.remove({}, { multi: true }, function (err) { + if (err) { return cb(err); } + + d.insert({ name: 'jako', age: 43, nid: 1 }, function () { + d.insert({ name: 'jakeb', age: 43, nid: 2 }, function () { + d.insert({ name: 'sue', age: 12, nid: 3 }, function () { + d.insert({ name: 'zoe', age: 23, nid: 4 }, function () { + d.insert({ name: 'jako', age: 35, nid: 5 }, function () { + return cb(); + }); + }); + }); + }); + }); + }); + } + , function (cb) { + var cursor = new Cursor(d, {}); + cursor.sort({ name: 1, age: -1 }).exec(function (err, docs) { + docs.length.should.equal(5); + + docs[0].nid.should.equal(2); + docs[1].nid.should.equal(1); + docs[2].nid.should.equal(5); + docs[3].nid.should.equal(3); + docs[4].nid.should.equal(4); + return cb(); + }); + } + , function (cb) { + var cursor = new Cursor(d, {}); + cursor.sort({ name: 1, age: 1 }).exec(function (err, docs) { + docs.length.should.equal(5); + + docs[0].nid.should.equal(2); + docs[1].nid.should.equal(5); + docs[2].nid.should.equal(1); + docs[3].nid.should.equal(3); + docs[4].nid.should.equal(4); + return cb(); + }); + } + , function (cb) { + var cursor = new Cursor(d, {}); + cursor.sort({ age: 1, name: 1 }).exec(function (err, docs) { + docs.length.should.equal(5); + + docs[0].nid.should.equal(3); + docs[1].nid.should.equal(4); + docs[2].nid.should.equal(5); + docs[3].nid.should.equal(2); + docs[4].nid.should.equal(1); + return cb(); + }); + } + , function (cb) { + var cursor = new Cursor(d, {}); + cursor.sort({ age: 1, name: -1 }).exec(function (err, docs) { + docs.length.should.equal(5); + + docs[0].nid.should.equal(3); + docs[1].nid.should.equal(4); + docs[2].nid.should.equal(5); + docs[3].nid.should.equal(1); + docs[4].nid.should.equal(2); + return cb(); + }); + } + ], done); }); }); // ===== End of 'Sorting' =====