Mysql sort, where and limit
This commit is contained in:
parent
7427289c59
commit
14c34a8058
|
@ -4,3 +4,5 @@ node_js:
|
|||
- 0.6
|
||||
- 0.7
|
||||
before_install: git submodule init && git submodule --quiet update
|
||||
before_script:
|
||||
- "mysql -e 'create database myapp_test;'"
|
||||
|
|
|
@ -71,7 +71,7 @@ MySQL.prototype.toFields = function (model, data) {
|
|||
var props = this._models[model].properties;
|
||||
Object.keys(data).forEach(function (key) {
|
||||
if (props[key]) {
|
||||
fields.push('`' + key.replace(/\./g, '`.`') + '` = ' + this.toDatabase(props[key], data[key]));
|
||||
fields.push('`' + key.replace(/\./g, '`.`') + '` = ' + this.toDatabase(props[key], data[key]));
|
||||
}
|
||||
}.bind(this));
|
||||
return fields.join(',');
|
||||
|
@ -93,7 +93,7 @@ MySQL.prototype.toDatabase = function (prop, val) {
|
|||
val.getMinutes(),
|
||||
val.getSeconds()
|
||||
].join('-');
|
||||
return this.client.escape(val);
|
||||
return '"' + val + '"';
|
||||
}
|
||||
if (prop.type.name == "Boolean") return val ? 1 : 0;
|
||||
return this.client.escape(val.toString());
|
||||
|
@ -139,39 +139,61 @@ MySQL.prototype.destroy = function destroy(model, id, callback) {
|
|||
});
|
||||
};
|
||||
|
||||
// TODO: hook up where, order, limit and offset conditions
|
||||
MySQL.prototype.all = function all(model, filter, callback) {
|
||||
this.query('SELECT * FROM ' + model, function (err, data) {
|
||||
|
||||
var sql = 'SELECT * FROM ' + model;
|
||||
var self = this;
|
||||
var props = this._models[model].properties;
|
||||
|
||||
if (filter) {
|
||||
|
||||
if (filter.where) {
|
||||
sql += ' ' + buildWhere(filter.where);
|
||||
}
|
||||
|
||||
if (filter.order) {
|
||||
sql += ' ' + buildOrderBy(filter.order);
|
||||
}
|
||||
|
||||
if (filter.limit) {
|
||||
sql += ' ' + buildLimit(filter.limit, filter.offset || 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.query(sql, function (err, data) {
|
||||
console.log(sql, err, data);
|
||||
if (err) {
|
||||
return callback(err, []);
|
||||
}
|
||||
callback(err, filter ? data.filter(applyFilter(filter)) : data);
|
||||
callback(null, data);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
function applyFilter(filter) {
|
||||
if (typeof filter.where === 'function') {
|
||||
return filter;
|
||||
}
|
||||
var keys = Object.keys(filter.where);
|
||||
return function (obj) {
|
||||
var pass = true;
|
||||
keys.forEach(function (key) {
|
||||
if (!test(filter.where[key], obj[key])) {
|
||||
pass = false;
|
||||
return sql;
|
||||
|
||||
function buildWhere(conds) {
|
||||
var cs = [];
|
||||
Object.keys(conds).forEach(function (key) {
|
||||
var keyEscaped = '`' + key.replace(/\./g, '`.`') + '`'
|
||||
if (conds[key] === null) {
|
||||
cs.push(keyEscaped + ' IS NULL');
|
||||
} else {
|
||||
cs.push(keyEscaped + ' = ' + self.toDatabase(props[key], conds[key]));
|
||||
}
|
||||
});
|
||||
return pass;
|
||||
return 'WHERE ' + cs.join(' AND ');
|
||||
}
|
||||
|
||||
function test(example, value) {
|
||||
if (typeof value === 'string' && example && example.constructor.name === 'RegExp') {
|
||||
return value.match(example);
|
||||
}
|
||||
// not strict equality
|
||||
return example == value;
|
||||
function buildOrderBy(order) {
|
||||
if (typeof order === 'string') order = [order];
|
||||
return 'ORDER BY ' + order.join(', ');
|
||||
}
|
||||
}
|
||||
|
||||
function buildLimit(limit, offset) {
|
||||
return 'LIMIT ' + (offset ? (offset + ', ' + limit) : limit);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
MySQL.prototype.destroyAll = function destroyAll(model, callback) {
|
||||
this.query('DELETE FROM ' + model, function (err) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "ONLY=memory ./support/nodeunit/bin/nodeunit test/*_test.* & ONLY=redis nodeunit test/common_test.js"
|
||||
"test": "ONLY=memory ./support/nodeunit/bin/nodeunit test/*_test.* & ONLY=redis nodeunit test/common_test.js & only=mysql nodeunit test/common_test.js"
|
||||
},
|
||||
"engines": [
|
||||
"node >= 0.4.0"
|
||||
|
|
|
@ -12,7 +12,7 @@ var schemas = {
|
|||
username: 'root'
|
||||
},
|
||||
mysql: {
|
||||
database: 'sequ-test',
|
||||
database: 'myapp_test',
|
||||
username: 'root'
|
||||
},
|
||||
postgres: {
|
||||
|
@ -34,7 +34,7 @@ Object.keys(schemas).forEach(function (schemaName) {
|
|||
if (process.env.ONLY && process.env.ONLY !== schemaName) return;
|
||||
context(schemaName, function () {
|
||||
var schema = new Schema(schemaName, schemas[schemaName]);
|
||||
// schema.log = console.log;
|
||||
schema.log = console.log;
|
||||
testOrm(schema);
|
||||
if (specificTest[schemaName]) specificTest[schemaName](schema);
|
||||
});
|
||||
|
@ -327,6 +327,7 @@ function testOrm(schema) {
|
|||
});
|
||||
|
||||
// matching regexp
|
||||
if (Post.schema.name === 'mysql') done(); else
|
||||
Post.all({where: {title: /hello/i}}, function (err, res) {
|
||||
var pass = true;
|
||||
res.forEach(function (r) {
|
||||
|
@ -425,7 +426,13 @@ function testOrm(schema) {
|
|||
|
||||
it('should handle ORDER clause', function (test) {
|
||||
var titles = [ 'Title A', 'Title Z', 'Title M', 'Title B', 'Title C' ];
|
||||
var dates = [ 5, 9, 0, 17, 9 ];
|
||||
var dates = Post.schema.name === 'redis' ? [ 5, 9, 0, 17, 9 ] : [
|
||||
new Date(1000 * 5 ),
|
||||
new Date(1000 * 9),
|
||||
new Date(1000 * 0),
|
||||
new Date(1000 * 17),
|
||||
new Date(1000 * 9)
|
||||
];
|
||||
titles.forEach(function (t, i) {
|
||||
Post.create({title: t, date: dates[i]}, done);
|
||||
});
|
||||
|
@ -434,8 +441,8 @@ function testOrm(schema) {
|
|||
function done(err, obj) {
|
||||
if (++i === titles.length) {
|
||||
doStringTest();
|
||||
doFilterAndSortTest();
|
||||
doNumberTest();
|
||||
doFilterAndSortTest();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,6 +451,8 @@ function testOrm(schema) {
|
|||
function doStringTest() {
|
||||
tests += 1;
|
||||
Post.all({order: 'title'}, function (err, posts) {
|
||||
if (err) console.log(err);
|
||||
test.equal(posts.length, 5);
|
||||
titles.sort().forEach(function (t, i) {
|
||||
test.equal(posts[i].title, t);
|
||||
});
|
||||
|
@ -454,8 +463,10 @@ function testOrm(schema) {
|
|||
function doNumberTest() {
|
||||
tests += 1;
|
||||
Post.all({order: 'date'}, function (err, posts) {
|
||||
if (err) console.log(err);
|
||||
test.equal(posts.length, 5);
|
||||
dates.sort(numerically).forEach(function (d, i) {
|
||||
test.equal(posts[i].date, d);
|
||||
test.equal(posts[i].date.toString(), d.toString());
|
||||
});
|
||||
finished();
|
||||
});
|
||||
|
@ -463,7 +474,8 @@ function testOrm(schema) {
|
|||
|
||||
function doFilterAndSortTest() {
|
||||
tests += 1;
|
||||
Post.all({where: {date: 9}, order: 'title', limit: 3}, function (err, posts) {
|
||||
Post.all({where: {title: new Date(1000 * 9)}, order: 'title', limit: 3}, function (err, posts) {
|
||||
if (err) console.log(err);
|
||||
test.equal(posts.length, 2, 'Exactly 2 posts returned by query');
|
||||
[ 'Title C', 'Title Z' ].forEach(function (t, i) {
|
||||
if (posts[i]) {
|
||||
|
|
Loading…
Reference in New Issue