added multiple sort for mongoose

This commit is contained in:
Jonathan Spies 2012-05-13 23:28:37 -05:00
parent 8e312bfe61
commit 3179c05b95
3 changed files with 132 additions and 19 deletions

61
coverage.html Normal file

File diff suppressed because one or more lines are too long

View File

@ -45,6 +45,7 @@ MongooseAdapter.prototype.define = function (descr) {
Object.keys(descr.properties).forEach(function (key) { Object.keys(descr.properties).forEach(function (key) {
props[key] = descr.properties[key].type; props[key] = descr.properties[key].type;
if (props[key].name === 'Text') props[key] = String; if (props[key].name === 'Text') props[key] = String;
if (props[key].name === 'Object') props[key] = mongoose.Schema.Types.Mixed;
}); });
var schema = new mongoose.Schema(props); var schema = new mongoose.Schema(props);
this._models[descr.model.modelName] = mongoose.model(descr.model.modelName, schema); this._models[descr.model.modelName] = mongoose.model(descr.model.modelName, schema);
@ -151,17 +152,21 @@ MongooseAdapter.prototype.all = function all(model, filter, callback) {
}); });
} }
if (filter.order) { if (filter.order) {
var m = filter.order.match(/\s+(A|DE)SC$/); var keys = filter.order; // can be Array or String
var key = filter.order; if (typeof(keys) == "string") {
var reverse = false; keys = keys.split(',');
if (m) {
key = key.replace(/\s+(A|DE)SC$/, '');
if (m[1] === 'DE') reverse = true;
} }
if (reverse) { var args = [];
query.desc(key);
} else { for(index in keys) {
query.asc(key); var m = keys[index].match(/\s+(A|DE)SC$/);
keys[index] = keys[index].replace(/\s+(A|DE)SC$/, '');
if (m && m[1] === 'DE') {
query.sort(keys[index].trim(), -1);
} else {
query.sort(keys[index].trim(), 1);
}
} }
} }
if (filter.limit) { if (filter.limit) {

View File

@ -59,11 +59,13 @@ function testOrm(schema) {
approved: Boolean, approved: Boolean,
joinedAt: Date, joinedAt: Date,
age: Number, age: Number,
passwd: String passwd: String,
extra: Object
}); });
Post = schema.define('Post', { Post = schema.define('Post', {
title: { type: String, length: 255, index: true }, title: { type: String, length: 255, index: true },
subject: { type: String },
content: { type: Text }, content: { type: Text },
date: { type: Date, default: Date.now, index: true }, date: { type: Date, default: Date.now, index: true },
published: { type: Boolean, default: false } published: { type: Boolean, default: false }
@ -143,7 +145,7 @@ function testOrm(schema) {
it('should be expoted to JSON', function (test) { it('should be expoted to JSON', function (test) {
test.equal(JSON.stringify(new Post({id: 1, title: 'hello, json', date: 1})), test.equal(JSON.stringify(new Post({id: 1, title: 'hello, json', date: 1})),
'{"id":1,"title":"hello, json","content":null,"date":1,"published":false,"userId":null}'); '{"id":1,"title":"hello, json","subject":null,"content":null,"date":1,"published":false,"userId":null}');
test.done(); test.done();
}); });
@ -473,17 +475,23 @@ function testOrm(schema) {
}); });
it('should handle ORDER clause', function (test) { it('should handle ORDER clause', function (test) {
var titles = [ 'Title A', 'Title Z', 'Title M', 'Title B', 'Title C' ]; var titles = [ { title: 'Title A', subject: "B" },
{ title: 'Title Z', subject: "A" },
{ title: 'Title M', subject: "C" },
{ title: 'Title A', subject: "A" },
{ title: 'Title B', subject: "A" },
{ title: 'Title C', subject: "D" }];
var isRedis = Post.schema.name === 'redis' || Post.schema.name === 'memory'; var isRedis = Post.schema.name === 'redis' || Post.schema.name === 'memory';
var dates = isRedis ? [ 5, 9, 0, 17, 9 ] : [ var dates = isRedis ? [ 5, 9, 0, 17, 10, 9 ] : [
new Date(1000 * 5 ), new Date(1000 * 5 ),
new Date(1000 * 9), new Date(1000 * 9),
new Date(1000 * 0), new Date(1000 * 0),
new Date(1000 * 17), new Date(1000 * 17),
new Date(1000 * 10),
new Date(1000 * 9) new Date(1000 * 9)
]; ];
titles.forEach(function (t, i) { titles.forEach(function (t, i) {
Post.create({title: t, date: dates[i]}, done); Post.create({title: t.title, subject: t.subject, date: dates[i]}, done);
}); });
var i = 0, tests = 0; var i = 0, tests = 0;
@ -493,18 +501,29 @@ function testOrm(schema) {
doFilterAndSortReverseTest(); doFilterAndSortReverseTest();
doStringTest(); doStringTest();
doNumberTest(); doNumberTest();
if (schema.name == 'mongoose') {
doMultipleSortTest();
doMultipleReverseSortTest();
}
} }
} }
function compare(a, b) {
if (a.title < b.title) return -1;
if (a.title > b.title) return 1;
return 0;
}
// Post.schema.log = console.log; // Post.schema.log = console.log;
function doStringTest() { function doStringTest() {
tests += 1; tests += 1;
Post.all({order: 'title'}, function (err, posts) { Post.all({order: 'title'}, function (err, posts) {
if (err) console.log(err); if (err) console.log(err);
test.equal(posts.length, 5); test.equal(posts.length, 6);
titles.sort().forEach(function (t, i) { titles.sort(compare).forEach(function (t, i) {
if (posts[i]) test.equal(posts[i].title, t); if (posts[i]) test.equal(posts[i].title, t.title);
}); });
finished(); finished();
}); });
@ -514,7 +533,7 @@ function testOrm(schema) {
tests += 1; tests += 1;
Post.all({order: 'date'}, function (err, posts) { Post.all({order: 'date'}, function (err, posts) {
if (err) console.log(err); if (err) console.log(err);
test.equal(posts.length, 5); test.equal(posts.length, 6);
dates.sort(numerically).forEach(function (d, i) { dates.sort(numerically).forEach(function (d, i) {
// fix inappropriated tz convert // fix inappropriated tz convert
if (posts[i]) if (posts[i])
@ -552,6 +571,34 @@ function testOrm(schema) {
}); });
} }
function doMultipleSortTest() {
tests += 1;
Post.all({order: "title ASC, subject ASC"}, function(err, posts) {
if (err) console.log(err);
test.equal(posts.length, 6);
test.equal(posts[0].title, "Title A");
test.equal(posts[0].subject, "A");
test.equal(posts[1].title, "Title A");
test.equal(posts[1].subject, "B");
test.equal(posts[5].title, "Title Z");
finished();
});
}
function doMultipleReverseSortTest() {
tests += 1;
Post.all({order: "title ASC, subject DESC"}, function(err, posts) {
if (err) console.log(err);
test.equal(posts.length, 6);
test.equal(posts[0].title, "Title A");
test.equal(posts[0].subject, "B");
test.equal(posts[1].title,"Title A");
test.equal(posts[1].subject, "A");
test.equal(posts[5].title, "Title Z");
finished();
});
}
var fin = 0; var fin = 0;
function finished() { function finished() {
if (++fin === tests) { if (++fin === tests) {