From 516c60de149402e153806c1bc933a1f1024d9fd6 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Mon, 18 Jul 2011 13:22:23 -0700 Subject: [PATCH] Sorting support. --- lib/mongo-mock/collection.js | 21 +++++++++-- test/test-collection.js | 12 ++++++ test/test-collection.out | 72 ++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/lib/mongo-mock/collection.js b/lib/mongo-mock/collection.js index e97c854..4edfef1 100644 --- a/lib/mongo-mock/collection.js +++ b/lib/mongo-mock/collection.js @@ -10,7 +10,7 @@ function collection(id, options) { if (typeof options === "function") { callback = options; options = null; } var objects = collection.filter(filter(query)); if (options) { - if (options.sort) options.sort(sorter(options.sort)); + if (options.sort) objects.sort(sorter(options.sort)); if (options.skip || ("limit" in options)) { var i = options.skip || 0; objects = objects.slice(i, i + (options.limit || Infinity)); @@ -150,9 +150,25 @@ function filter(fields) { }; } -// TODO function sorter(sort) { + + function value(o, k) { + var keys = k.split("."), i = -1, n = keys.length; + while (++i < n) { + if (!((k = keys[i]) in o)) return; + o = o[k]; + } + return o; + } + return function(a, b) { + for (var key in sort) { + var va = value(a, key), + vb = value(b, key), + vk = sort[key]; + if (va < vb) return -vk; + if (va > vb) return vk; + } return 0; }; } @@ -220,7 +236,6 @@ var filter_operators = { $regex: function(a, b) { return b.test(a); } }; - // TOOD $inc // TODO $push // TODO $pushAll diff --git a/test/test-collection.js b/test/test-collection.js index 022c530..257b216 100644 --- a/test/test-collection.js +++ b/test/test-collection.js @@ -134,6 +134,18 @@ db.open(function(error) { }); }); +db.open(function(error) { + db.collection("sort", function(error, collection) { + for (var i = 10; --i >= 0;) collection.insert({key: i, group: (~~(i / 3) + 3) % 3}); + collection.find({}, {sort: {key: 1}}, log("sort(key)")); + collection.find({}, {sort: {key: -1}}, log("sort(-key)")); + collection.find({}, {sort: {group: 1, key: 1}}, log("sort(group, key)")); + collection.find({}, {sort: {group: 1, key: -1}}, log("sort(group, -key)")); + collection.find({}, {sort: {group: -1, key: 1}}, log("sort(-group, key)")); + collection.find({}, {sort: {group: -1, key: -1}}, log("sort(-group, -key)")); + }); +}); + function log(message) { return function(error, cursor) { console.log(message + ":"); diff --git a/test/test-collection.out b/test/test-collection.out index 4c896aa..1db79dc 100644 --- a/test/test-collection.out +++ b/test/test-collection.out @@ -166,3 +166,75 @@ update($set(object.field)): update($unset): {"foo":"bar","_id":"4e21d7de0123ab012300000a"} +sort(key): + {"key":0,"group":0,"_id":"4e21d7e80123ab0123000014"} + {"key":1,"group":0,"_id":"4e21d7e70123ab0123000013"} + {"key":2,"group":0,"_id":"4e21d7e60123ab0123000012"} + {"key":3,"group":1,"_id":"4e21d7e50123ab0123000011"} + {"key":4,"group":1,"_id":"4e21d7e40123ab0123000010"} + {"key":5,"group":1,"_id":"4e21d7e30123ab012300000f"} + {"key":6,"group":2,"_id":"4e21d7e20123ab012300000e"} + {"key":7,"group":2,"_id":"4e21d7e10123ab012300000d"} + {"key":8,"group":2,"_id":"4e21d7e00123ab012300000c"} + {"key":9,"group":0,"_id":"4e21d7df0123ab012300000b"} + +sort(-key): + {"key":9,"group":0,"_id":"4e21d7df0123ab012300000b"} + {"key":8,"group":2,"_id":"4e21d7e00123ab012300000c"} + {"key":7,"group":2,"_id":"4e21d7e10123ab012300000d"} + {"key":6,"group":2,"_id":"4e21d7e20123ab012300000e"} + {"key":5,"group":1,"_id":"4e21d7e30123ab012300000f"} + {"key":4,"group":1,"_id":"4e21d7e40123ab0123000010"} + {"key":3,"group":1,"_id":"4e21d7e50123ab0123000011"} + {"key":2,"group":0,"_id":"4e21d7e60123ab0123000012"} + {"key":1,"group":0,"_id":"4e21d7e70123ab0123000013"} + {"key":0,"group":0,"_id":"4e21d7e80123ab0123000014"} + +sort(group, key): + {"key":0,"group":0,"_id":"4e21d7e80123ab0123000014"} + {"key":1,"group":0,"_id":"4e21d7e70123ab0123000013"} + {"key":2,"group":0,"_id":"4e21d7e60123ab0123000012"} + {"key":9,"group":0,"_id":"4e21d7df0123ab012300000b"} + {"key":3,"group":1,"_id":"4e21d7e50123ab0123000011"} + {"key":4,"group":1,"_id":"4e21d7e40123ab0123000010"} + {"key":5,"group":1,"_id":"4e21d7e30123ab012300000f"} + {"key":6,"group":2,"_id":"4e21d7e20123ab012300000e"} + {"key":7,"group":2,"_id":"4e21d7e10123ab012300000d"} + {"key":8,"group":2,"_id":"4e21d7e00123ab012300000c"} + +sort(group, -key): + {"key":9,"group":0,"_id":"4e21d7df0123ab012300000b"} + {"key":2,"group":0,"_id":"4e21d7e60123ab0123000012"} + {"key":1,"group":0,"_id":"4e21d7e70123ab0123000013"} + {"key":0,"group":0,"_id":"4e21d7e80123ab0123000014"} + {"key":5,"group":1,"_id":"4e21d7e30123ab012300000f"} + {"key":4,"group":1,"_id":"4e21d7e40123ab0123000010"} + {"key":3,"group":1,"_id":"4e21d7e50123ab0123000011"} + {"key":8,"group":2,"_id":"4e21d7e00123ab012300000c"} + {"key":7,"group":2,"_id":"4e21d7e10123ab012300000d"} + {"key":6,"group":2,"_id":"4e21d7e20123ab012300000e"} + +sort(-group, key): + {"key":6,"group":2,"_id":"4e21d7e20123ab012300000e"} + {"key":7,"group":2,"_id":"4e21d7e10123ab012300000d"} + {"key":8,"group":2,"_id":"4e21d7e00123ab012300000c"} + {"key":3,"group":1,"_id":"4e21d7e50123ab0123000011"} + {"key":4,"group":1,"_id":"4e21d7e40123ab0123000010"} + {"key":5,"group":1,"_id":"4e21d7e30123ab012300000f"} + {"key":0,"group":0,"_id":"4e21d7e80123ab0123000014"} + {"key":1,"group":0,"_id":"4e21d7e70123ab0123000013"} + {"key":2,"group":0,"_id":"4e21d7e60123ab0123000012"} + {"key":9,"group":0,"_id":"4e21d7df0123ab012300000b"} + +sort(-group, -key): + {"key":8,"group":2,"_id":"4e21d7e00123ab012300000c"} + {"key":7,"group":2,"_id":"4e21d7e10123ab012300000d"} + {"key":6,"group":2,"_id":"4e21d7e20123ab012300000e"} + {"key":5,"group":1,"_id":"4e21d7e30123ab012300000f"} + {"key":4,"group":1,"_id":"4e21d7e40123ab0123000010"} + {"key":3,"group":1,"_id":"4e21d7e50123ab0123000011"} + {"key":9,"group":0,"_id":"4e21d7df0123ab012300000b"} + {"key":2,"group":0,"_id":"4e21d7e60123ab0123000012"} + {"key":1,"group":0,"_id":"4e21d7e70123ab0123000013"} + {"key":0,"group":0,"_id":"4e21d7e80123ab0123000014"} +