diff --git a/packages/minimongo/package.js b/packages/minimongo/package.js index 3852607ee0..1b76f2c6b3 100644 --- a/packages/minimongo/package.js +++ b/packages/minimongo/package.js @@ -13,7 +13,6 @@ Package.on_use(function (api, where) { api.add_files([ 'minimongo.js', 'selector.js', - 'sort.js', 'uuid.js', 'modify.js', 'diff.js' diff --git a/packages/minimongo/selector.js b/packages/minimongo/selector.js index b2def5735c..b92db74f9f 100644 --- a/packages/minimongo/selector.js +++ b/packages/minimongo/selector.js @@ -543,4 +543,62 @@ LocalCollection._selectorIsId = function (selector) { return (typeof selector === "string") || (typeof selector === "number"); }; +// Give a sort spec, which can be in any of these forms: +// {"key1": 1, "key2": -1} +// [["key1", "asc"], ["key2", "desc"]] +// ["key1", ["key2", "desc"]] +// +// (.. with the first form being dependent on the key enumeration +// behavior of your javascript VM, which usually does what you mean in +// this case if the key names don't look like integers ..) +// +// return a function that takes two objects, and returns -1 if the +// first object comes first in order, 1 if the second object comes +// first, or 0 if neither object comes before the other. + +LocalCollection._compileSort = function (spec) { + var sortSpecParts = []; + + if (spec instanceof Array) { + for (var i = 0; i < spec.length; i++) { + if (typeof spec[i] === "string") { + sortSpecParts.push({ + lookup: makeLookupFunction(spec[i]), + ascending: true + }); + } else { + sortSpecParts.push({ + lookup: makeLookupFunction(spec[i][0]), + ascending: spec[i][1] !== "desc" + }); + } + } + } else if (typeof spec === "object") { + for (var key in spec) { + sortSpecParts.push({ + lookup: makeLookupFunction(key), + ascending: spec[key] >= 0 + }); + } + } else { + throw Error("Bad sort specification: ", JSON.stringify(spec)); + } + + if (sortSpecParts.length === 0) + return function () {return 0;}; + + return function (a, b) { + for (var i = 0; i < sortSpecParts.length; ++i) { + var specPart = sortSpecParts[i]; + var aValue = specPart.lookup(a); + var bValue = specPart.lookup(b); + var compare = LocalCollection._f._cmp(aValue, bValue); + if (compare !== 0) + return specPart.ascending ? compare : -compare; + }; + return 0; + }; +}; + + })(); diff --git a/packages/minimongo/sort.js b/packages/minimongo/sort.js deleted file mode 100644 index 94420cf237..0000000000 --- a/packages/minimongo/sort.js +++ /dev/null @@ -1,65 +0,0 @@ -// Give a sort spec, which can be in any of these forms: -// {"key1": 1, "key2": -1} -// [["key1", "asc"], ["key2", "desc"]] -// ["key1", ["key2", "desc"]] -// -// (.. with the first form being dependent on the key enumeration -// behavior of your javascript VM, which usually does what you mean in -// this case if the key names don't look like integers ..) -// -// return a function that takes two objects, and returns -1 if the -// first object comes first in order, 1 if the second object comes -// first, or 0 if neither object comes before the other. - -LocalCollection._compileSort = function (spec) { - var keys = []; - var asc = []; - - if (spec instanceof Array) { - for (var i = 0; i < spec.length; i++) { - if (typeof spec[i] === "string") { - keys.push(spec[i]); - asc.push(true); - } else { - keys.push(spec[i][0]); - asc.push(spec[i][1] !== "desc"); - } - } - } else if (typeof spec === "object") { - for (key in spec) { - keys.push(key); - asc.push(!(spec[key] < 0)); - } - } else { - throw Error("Bad sort specification: ", JSON.stringify(spec)); - } - - if (keys.length === 0) - return function () {return 0;}; - - // eval() does not return a value in IE8, nor does the spec say it - // should. Assign to a local to get the value, instead. - var _func; - var code = "_func = (function(c){return function(a,b){var x;"; - for (var i = 0; i < keys.length; i++) { - // handle dotted subpaths. Make sure to avoid dereferencing - // undefined if a subkey doesn't exist. - var splittedKeys = keys[i].split("."); - var keyString = ""; - var aCode = "a"; - var bCode = "b"; - for(var o = 0; o < splittedKeys.length; o++) { - keyString = keyString + "[" + JSON.stringify(splittedKeys[o]) + "]"; - aCode += '&&a' + keyString; - bCode += '&&b' + keyString; - } - if (i !== 0) { - code += "if(x!==0)return x;"; - } - code += "x=" + (asc[i] ? "" : "-") + - "c(" + aCode + "," + bCode + ");"; - } - code += "return x;};})"; - eval(code); - return _func(LocalCollection._f._cmp); -};