From 792279b7bf154ecf03aebc5f91c7d146e6f8a128 Mon Sep 17 00:00:00 2001 From: Diogo Resende Date: Mon, 15 Apr 2013 22:25:43 +0100 Subject: [PATCH] Adds support for descending ordering using "-property" (#115) --- lib/ChainFind.js | 5 +++- lib/Drivers/DML/mysql.js | 4 ++- lib/Drivers/DML/postgres.js | 4 ++- lib/Drivers/DML/postgresaxomic.js | 4 ++- lib/Drivers/DML/sqlite.js | 4 ++- lib/Model.js | 5 ++++ lib/Utilities.js | 46 +++++++++++++++++++++++++++++++ 7 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 lib/Utilities.js diff --git a/lib/ChainFind.js b/lib/ChainFind.js index 41c6479a..f682df37 100644 --- a/lib/ChainFind.js +++ b/lib/ChainFind.js @@ -25,7 +25,10 @@ function ChainFind(opts) { return this; }, order: function (property, order) { - opts.order = [ property, order ]; + if (!Array.isArray(opts.order)) { + opts.order = []; + } + opts.order.push([ property, (order && order.toUpperCase() == "Z" ? "Z" : "A") ]); return this; }, count: function (cb) { diff --git a/lib/Drivers/DML/mysql.js b/lib/Drivers/DML/mysql.js index ed300039..ecc8843e 100644 --- a/lib/Drivers/DML/mysql.js +++ b/lib/Drivers/DML/mysql.js @@ -99,7 +99,9 @@ Driver.prototype.find = function (fields, table, conditions, opts, cb) { q.limit('18446744073709551615'); } if (opts.order) { - q.order(opts.order[0], opts.order[1]); + for (var i = 0; i < opts.order.length; i++) { + q.order(opts.order[i][0], opts.order[i][1]); + } } if (opts.merge) { diff --git a/lib/Drivers/DML/postgres.js b/lib/Drivers/DML/postgres.js index 067a9bdc..f9a485d7 100644 --- a/lib/Drivers/DML/postgres.js +++ b/lib/Drivers/DML/postgres.js @@ -74,7 +74,9 @@ Driver.prototype.find = function (fields, table, conditions, opts, cb) { q.limit(opts.limit); } if (opts.order) { - q.order(opts.order[0], opts.order[1]); + for (var i = 0; i < opts.order.length; i++) { + q.order(opts.order[i][0], opts.order[i][1]); + } } if (opts.merge) { diff --git a/lib/Drivers/DML/postgresaxomic.js b/lib/Drivers/DML/postgresaxomic.js index 4a7a983a..97ed16db 100644 --- a/lib/Drivers/DML/postgresaxomic.js +++ b/lib/Drivers/DML/postgresaxomic.js @@ -73,7 +73,9 @@ Driver.prototype.find = function (fields, table, conditions, opts, cb) { q.limit(opts.limit); } if (opts.order) { - q.order(opts.order[0], opts.order[1]); + for (var i = 0; i < opts.order.length; i++) { + q.order(opts.order[i][0], opts.order[i][1]); + } } if (opts.merge) { diff --git a/lib/Drivers/DML/sqlite.js b/lib/Drivers/DML/sqlite.js index ab76794f..e1ef7b9b 100644 --- a/lib/Drivers/DML/sqlite.js +++ b/lib/Drivers/DML/sqlite.js @@ -74,7 +74,9 @@ Driver.prototype.find = function (fields, table, conditions, opts, cb) { q.limit('9223372036854775807'); } if (opts.order) { - q.order(opts.order[0], opts.order[1]); + for (var i = 0; i < opts.order.length; i++) { + q.order(opts.order[i][0], opts.order[i][1]); + } } if (opts.merge) { diff --git a/lib/Model.js b/lib/Model.js index e7657dca..99a6bd39 100644 --- a/lib/Model.js +++ b/lib/Model.js @@ -4,6 +4,7 @@ var OneAssociation = require("./Associations/One"); var ManyAssociation = require("./Associations/Many"); var ChainFind = require("./ChainFind"); var LazyLoad = require("./LazyLoad"); +var Utilities = require("./Utilities"); exports.Model = Model; @@ -224,6 +225,10 @@ function Model(opts) { options.cache = opts.cache; } + if (order) { + order = Utilities.standardizeOrder(order); + } + var chain = new ChainFind({ only : options.only || model_fields, id : opts.id, diff --git a/lib/Utilities.js b/lib/Utilities.js new file mode 100644 index 00000000..a5afe76a --- /dev/null +++ b/lib/Utilities.js @@ -0,0 +1,46 @@ +/** + * Order should be a String (with the property name assumed ascending) + * or an Array or property String names. + * + * Examples: + * + * 1. 'property1' (ORDER BY property1 ASC) + * 2. '-property1' (ORDER BY property1 DESC) + * 3. [ 'property1' ] (ORDER BY property1 ASC) + * 4. [ '-property1' ] (ORDER BY property1 DESC) + * 5. [ 'property1', 'A' ] (ORDER BY property1 ASC) + * 6. [ 'property1', 'Z' ] (ORDER BY property1 DESC) + * 7. [ '-property1', 'A' ] (ORDER BY property1 ASC) + * 8. [ 'property1', 'property2' ] (ORDER BY property1 ASC, property2 ASC) + * 9. [ 'property1', '-property2' ] (ORDER BY property1 ASC, property2 DESC) + * ... + */ + +exports.standardizeOrder = function (order) { + if (typeof order == "string") { + if (order[0] == "-") { + return [ [ order.substr(1), "Z" ] ]; + } + return [ [ order, "A" ] ]; + } + + var new_order = [], minus; + + for (var i = 0; i < order.length; i++) { + minus = (order[i][0] == "-"); + + if (i < order.length - 1 && [ "A", "Z" ].indexOf(order[i + 1].toUpperCase()) >= 0) { + new_order.push([ + (minus ? order[i].substr(1) : order[i]), + order[i + 1] + ]); + i += 1; + } else if (minus) { + new_order.push([ order[i].substr(1), "Z" ]); + } else { + new_order.push([ order[i], "A" ]); + } + } + + return new_order; +};