Model.count with params support, fix time in mysql
This commit is contained in:
parent
b237b7bd4c
commit
ad7d1d568a
|
@ -243,8 +243,12 @@ AbstractClass.destroyAll = function destroyAll(cb) {
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
AbstractClass.count = function (cb) {
|
AbstractClass.count = function (where, cb) {
|
||||||
this.schema.adapter.count(this.modelName, cb);
|
if (typeof where === 'function') {
|
||||||
|
cb = where;
|
||||||
|
where = null;
|
||||||
|
}
|
||||||
|
this.schema.adapter.count(this.modelName, cb, where);
|
||||||
};
|
};
|
||||||
|
|
||||||
AbstractClass.toString = function () {
|
AbstractClass.toString = function () {
|
||||||
|
|
|
@ -119,8 +119,21 @@ Memory.prototype.destroyAll = function destroyAll(model, callback) {
|
||||||
callback();
|
callback();
|
||||||
};
|
};
|
||||||
|
|
||||||
Memory.prototype.count = function count(model, callback) {
|
Memory.prototype.count = function count(model, callback, where) {
|
||||||
callback(null, Object.keys(this.cache[model]).length);
|
var cache = this.cache[model];
|
||||||
|
var data = Object.keys(cache)
|
||||||
|
if (where) {
|
||||||
|
data = data.filter(function (id) {
|
||||||
|
var ok = true;
|
||||||
|
Object.keys(where).forEach(function (key) {
|
||||||
|
if (cache[id][key] != where[key]) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return ok;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
callback(null, data.length);
|
||||||
};
|
};
|
||||||
|
|
||||||
Memory.prototype.updateAttributes = function updateAttributes(model, id, data, cb) {
|
Memory.prototype.updateAttributes = function updateAttributes(model, id, data, cb) {
|
||||||
|
|
|
@ -15,7 +15,8 @@ exports.initialize = function initializeSchema(schema, callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
schema.adapter = new MySQL(schema.client);
|
schema.adapter = new MySQL(schema.client);
|
||||||
process.nextTick(callback);
|
schema.client.query('SET TIME_ZONE = "+04:00"', callback);
|
||||||
|
// process.nextTick(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
function MySQL(client) {
|
function MySQL(client) {
|
||||||
|
@ -77,6 +78,19 @@ MySQL.prototype.toFields = function (model, data) {
|
||||||
return fields.join(',');
|
return fields.join(',');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function dateToMysql(val) {
|
||||||
|
return val.getUTCFullYear() + '-' +
|
||||||
|
fillZeros(val.getUTCMonth() + 1) + '-' +
|
||||||
|
fillZeros(val.getUTCDate()) + ' ' +
|
||||||
|
fillZeros(val.getUTCHours()) + ':' +
|
||||||
|
fillZeros(val.getUTCMinutes()) + ':' +
|
||||||
|
fillZeros(val.getUTCSeconds());
|
||||||
|
|
||||||
|
function fillZeros(v) {
|
||||||
|
return v < 10 ? '0' + v : v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MySQL.prototype.toDatabase = function (prop, val) {
|
MySQL.prototype.toDatabase = function (prop, val) {
|
||||||
if (prop.type.name === 'Number') return val;
|
if (prop.type.name === 'Number') return val;
|
||||||
if (val === null) return 'NULL';
|
if (val === null) return 'NULL';
|
||||||
|
@ -85,15 +99,7 @@ MySQL.prototype.toDatabase = function (prop, val) {
|
||||||
if (!val.toUTCString) {
|
if (!val.toUTCString) {
|
||||||
val = new Date(val);
|
val = new Date(val);
|
||||||
}
|
}
|
||||||
val = [
|
return '"' + dateToMysql(val) + '"';
|
||||||
val.getFullYear(),
|
|
||||||
val.getMonth() + 1,
|
|
||||||
val.getDate(),
|
|
||||||
val.getHours(),
|
|
||||||
val.getMinutes(),
|
|
||||||
val.getSeconds()
|
|
||||||
].join('-');
|
|
||||||
return '"' + val + '"';
|
|
||||||
}
|
}
|
||||||
if (prop.type.name == "Boolean") return val ? 1 : 0;
|
if (prop.type.name == "Boolean") return val ? 1 : 0;
|
||||||
return this.client.escape(val.toString());
|
return this.client.escape(val.toString());
|
||||||
|
@ -105,7 +111,9 @@ MySQL.prototype.fromDatabase = function (model, data) {
|
||||||
Object.keys(data).forEach(function (key) {
|
Object.keys(data).forEach(function (key) {
|
||||||
var val = data[key];
|
var val = data[key];
|
||||||
if (props[key]) {
|
if (props[key]) {
|
||||||
// if (props[key])
|
if (props[key].type.name === 'Date') {
|
||||||
|
val = new Date(val.toString().replace(/GMT.*$/, 'GMT'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
data[key] = val;
|
data[key] = val;
|
||||||
});
|
});
|
||||||
|
@ -165,7 +173,9 @@ MySQL.prototype.all = function all(model, filter, callback) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err, []);
|
return callback(err, []);
|
||||||
}
|
}
|
||||||
callback(null, data);
|
callback(null, data.map(function (obj) {
|
||||||
|
return self.fromDatabase(model, obj);
|
||||||
|
}));
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
return sql;
|
return sql;
|
||||||
|
@ -203,10 +213,26 @@ MySQL.prototype.destroyAll = function destroyAll(model, callback) {
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
MySQL.prototype.count = function count(model, callback) {
|
MySQL.prototype.count = function count(model, callback, where) {
|
||||||
this.query('SELECT count(*) as cnt FROM ' + model, function (err, res) {
|
var self = this;
|
||||||
|
var props = this._models[model].properties;
|
||||||
|
|
||||||
|
this.query('SELECT count(*) as cnt FROM ' + model + buildWhere(where), function (err, res) {
|
||||||
callback(err, err ? null : res[0].cnt);
|
callback(err, err ? null : res[0].cnt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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 cs.length ? ' WHERE ' + cs.join(' AND ') : '';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MySQL.prototype.updateAttributes = function updateAttrs(model, id, data, cb) {
|
MySQL.prototype.updateAttributes = function updateAttrs(model, id, data, cb) {
|
||||||
|
|
|
@ -254,10 +254,21 @@ Neo4j.prototype.destroy = function destroy(model, id, callback) {
|
||||||
Neo4j.prototype.all = function all(model, filter, callback) {
|
Neo4j.prototype.all = function all(model, filter, callback) {
|
||||||
this.client.queryNodeIndex(model, 'id:*', function (err, nodes) {
|
this.client.queryNodeIndex(model, 'id:*', function (err, nodes) {
|
||||||
if (nodes) {
|
if (nodes) {
|
||||||
nodes = nodes.map(function (s) { s.data.id = s.id; return s.data });
|
nodes = nodes.map(function (obj) {
|
||||||
|
obj.data.id = obj.id;
|
||||||
|
return this.readFromDb(model, obj.data);
|
||||||
|
}.bind(this));
|
||||||
}
|
}
|
||||||
callback(err, filter && nodes ? nodes.filter(applyFilter(filter)) : nodes);
|
if (filter) {
|
||||||
});
|
nodes = nodes ? nodes.filter(applyFilter(filter)) : nodes;
|
||||||
|
if (filter.order) {
|
||||||
|
nodes = nodes.sort(function (a, b) {
|
||||||
|
return a[filter.order] > b[filter.order];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(err, nodes);
|
||||||
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
Neo4j.prototype.allNodes = function all(model, callback) {
|
Neo4j.prototype.allNodes = function all(model, callback) {
|
||||||
|
@ -285,6 +296,10 @@ function applyFilter(filter) {
|
||||||
if (typeof value === 'string' && example && example.constructor.name === 'RegExp') {
|
if (typeof value === 'string' && example && example.constructor.name === 'RegExp') {
|
||||||
return value.match(example);
|
return value.match(example);
|
||||||
}
|
}
|
||||||
|
if (typeof value === 'object' && value.constructor.name === 'Date' && typeof example === 'object' && example.constructor.name === 'Date') {
|
||||||
|
return example.toString() === value.toString();
|
||||||
|
}
|
||||||
|
console.log(example,'==', value, example == value);
|
||||||
// not strict equality
|
// not strict equality
|
||||||
return example == value;
|
return example == value;
|
||||||
}
|
}
|
||||||
|
@ -308,8 +323,8 @@ Neo4j.prototype.destroyAll = function destroyAll(model, callback) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Neo4j.prototype.count = function count(model, callback) {
|
Neo4j.prototype.count = function count(model, callback, conds) {
|
||||||
this.all(model, null, function (err, collection) {
|
this.all(model, {where: conds}, function (err, collection) {
|
||||||
callback(err, collection ? collection.length : 0);
|
callback(err, collection ? collection.length : 0);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -93,6 +93,22 @@ PG.prototype.toFields = function (model, data, forCreate) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function dateToPostgres(val) {
|
||||||
|
return [
|
||||||
|
val.getUTCFullYear(),
|
||||||
|
fz(val.getUTCMonth() + 1),
|
||||||
|
fz(val.getUTCDate())
|
||||||
|
].join('-') + ' ' + [
|
||||||
|
fz(val.getUTCHours()),
|
||||||
|
fz(val.getUTCMinutes()),
|
||||||
|
fz(val.getUTCSeconds())
|
||||||
|
].join(':');
|
||||||
|
|
||||||
|
function fz(v) {
|
||||||
|
return v < 10 ? '0' + v : v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PG.prototype.toDatabase = function (prop, val) {
|
PG.prototype.toDatabase = function (prop, val) {
|
||||||
if (val === null) return 'NULL';
|
if (val === null) return 'NULL';
|
||||||
if (prop.type.name === 'Number') return val;
|
if (prop.type.name === 'Number') return val;
|
||||||
|
@ -101,18 +117,10 @@ PG.prototype.toDatabase = function (prop, val) {
|
||||||
if (!val.toUTCString) {
|
if (!val.toUTCString) {
|
||||||
val = new Date(val);
|
val = new Date(val);
|
||||||
}
|
}
|
||||||
val = [
|
return escape(dateToPostgres(val));
|
||||||
val.getUTCFullYear(),
|
|
||||||
val.getUTCMonth() + 1,
|
|
||||||
val.getUTCDate()
|
|
||||||
].join('-') + ' ' + [
|
|
||||||
val.getUTCHours(),
|
|
||||||
val.getUTCMinutes(),
|
|
||||||
val.getUTCSeconds()
|
|
||||||
].join(':');
|
|
||||||
return escape(val);
|
|
||||||
}
|
}
|
||||||
return escape(val.toString());
|
return escape(val.toString());
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PG.prototype.fromDatabase = function (model, data) {
|
PG.prototype.fromDatabase = function (model, data) {
|
||||||
|
@ -161,7 +169,7 @@ PG.prototype.all = function all(model, filter, callback) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err, []);
|
return callback(err, []);
|
||||||
}
|
}
|
||||||
callback(err, filter ? data.items.filter(applyFilter(filter)) : data.items);
|
callback(err, filter && filter.where ? data.items.filter(applyFilter(filter)) : data.items);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -171,7 +179,7 @@ PG.prototype.toFilter = function (model, filter) {
|
||||||
}
|
}
|
||||||
if (!filter) return '';
|
if (!filter) return '';
|
||||||
var props = this._models[model].properties;
|
var props = this._models[model].properties;
|
||||||
var out='';
|
var out = '';
|
||||||
if (filter.where) {
|
if (filter.where) {
|
||||||
var fields = [];
|
var fields = [];
|
||||||
Object.keys(filter.where).forEach(function (key) {
|
Object.keys(filter.where).forEach(function (key) {
|
||||||
|
@ -188,9 +196,18 @@ PG.prototype.toFilter = function (model, filter) {
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
if (fields.length) {
|
if (fields.length) {
|
||||||
out += ' where ' + fields.join(' AND ');
|
out += ' WHERE ' + fields.join(' AND ');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter.order) {
|
||||||
|
out += ' ORDER BY ' + filter.order;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.limit) {
|
||||||
|
out += ' LIMIT ' + filter.limit + ' ' + (filter.offset || '');
|
||||||
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -228,11 +245,26 @@ PG.prototype.destroyAll = function destroyAll(model, callback) {
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
PG.prototype.count = function count(model, callback) {
|
PG.prototype.count = function count(model, callback, where) {
|
||||||
this.query('SELECT count(*) as cnt FROM "' + model + '"', function (err, res) {
|
var self = this;
|
||||||
|
var props = this._models[model].properties;
|
||||||
|
|
||||||
|
this.query('SELECT count(*) as cnt FROM "' + model + '"' + buildWhere(where), function (err, res) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
callback(err, res && res.items[0] && res.items[0].cnt);
|
callback(err, res && res.items[0] && res.items[0].cnt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function buildWhere(conds) {
|
||||||
|
var cs = [];
|
||||||
|
Object.keys(conds || {}).forEach(function (key) {
|
||||||
|
if (conds[key] === null) {
|
||||||
|
cs.push(key + ' IS NULL');
|
||||||
|
} else {
|
||||||
|
cs.push(key + ' = ' + self.toDatabase(props[key], conds[key]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return cs.length ? ' WHERE ' + cs.join(' AND ') : '';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PG.prototype.updateAttributes = function updateAttrs(model, id, data, cb) {
|
PG.prototype.updateAttributes = function updateAttrs(model, id, data, cb) {
|
||||||
|
|
|
@ -366,13 +366,19 @@ BridgeToRedis.prototype.destroyAll = function destroyAll(model, callback) {
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
BridgeToRedis.prototype.count = function count(model, callback) {
|
BridgeToRedis.prototype.count = function count(model, callback, where) {
|
||||||
var keysQuery = model + ':*';
|
var keysQuery = model + ':*';
|
||||||
var t1 = Date.now();
|
var t1 = Date.now();
|
||||||
this.client.keys(keysQuery, function (err, keys) {
|
if (where && Object.keys(where).length) {
|
||||||
this.log('KEYS ' + keysQuery, t1);
|
this.all(model, {where: where}, function (err, data) {
|
||||||
callback(err, err ? null : keys.length);
|
callback(err, err ? null : data.length);
|
||||||
}.bind(this));
|
});
|
||||||
|
} else {
|
||||||
|
this.client.keys(keysQuery, function (err, keys) {
|
||||||
|
this.log('KEYS ' + keysQuery, t1);
|
||||||
|
callback(err, err ? null : keys.length);
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BridgeToRedis.prototype.updateAttributes = function updateAttrs(model, id, data, cb) {
|
BridgeToRedis.prototype.updateAttributes = function updateAttrs(model, id, data, cb) {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
},
|
},
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "ONLY=memory ./support/nodeunit/bin/nodeunit test/*_test.* && ONLY=redis nodeunit test/common_test.js && ONLY=mysql 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 && ONLY=postgres nodeunit test/common_test.js"
|
||||||
},
|
},
|
||||||
"engines": [
|
"engines": [
|
||||||
"node >= 0.4.0"
|
"node >= 0.4.0"
|
||||||
|
|
|
@ -297,12 +297,15 @@ function testOrm(schema) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var countOfposts;
|
var countOfposts, countOfpostsFiltered;
|
||||||
it('should fetch collection', function (test) {
|
it('should fetch collection', function (test) {
|
||||||
Post.all(function (err, posts) {
|
Post.all(function (err, posts) {
|
||||||
countOfposts = posts.length;
|
countOfposts = posts.length;
|
||||||
test.ok(countOfposts > 0);
|
test.ok(countOfposts > 0);
|
||||||
test.ok(posts[0] instanceof Post);
|
test.ok(posts[0] instanceof Post);
|
||||||
|
countOfpostsFiltered = posts.filter(function (p) {
|
||||||
|
return p.title === 'title';
|
||||||
|
}).length;
|
||||||
test.done();
|
test.done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -310,7 +313,10 @@ function testOrm(schema) {
|
||||||
it('should fetch count of records in collection', function (test) {
|
it('should fetch count of records in collection', function (test) {
|
||||||
Post.count(function (err, count) {
|
Post.count(function (err, count) {
|
||||||
test.equal(countOfposts, count);
|
test.equal(countOfposts, count);
|
||||||
test.done();
|
Post.count({title: 'title'}, function (err, count) {
|
||||||
|
test.equal(countOfpostsFiltered, count);
|
||||||
|
test.done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -481,6 +487,7 @@ function testOrm(schema) {
|
||||||
if (err) console.log(err);
|
if (err) console.log(err);
|
||||||
test.equal(posts.length, 5);
|
test.equal(posts.length, 5);
|
||||||
dates.sort(numerically).forEach(function (d, i) {
|
dates.sort(numerically).forEach(function (d, i) {
|
||||||
|
// fix inappropriated tz convert
|
||||||
test.equal(posts[i].date.toString(), d.toString());
|
test.equal(posts[i].date.toString(), d.toString());
|
||||||
});
|
});
|
||||||
finished();
|
finished();
|
||||||
|
|
Loading…
Reference in New Issue