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));
|
||||
};
|
||||
|
||||
AbstractClass.count = function (cb) {
|
||||
this.schema.adapter.count(this.modelName, cb);
|
||||
AbstractClass.count = function (where, cb) {
|
||||
if (typeof where === 'function') {
|
||||
cb = where;
|
||||
where = null;
|
||||
}
|
||||
this.schema.adapter.count(this.modelName, cb, where);
|
||||
};
|
||||
|
||||
AbstractClass.toString = function () {
|
||||
|
|
|
@ -119,8 +119,21 @@ Memory.prototype.destroyAll = function destroyAll(model, callback) {
|
|||
callback();
|
||||
};
|
||||
|
||||
Memory.prototype.count = function count(model, callback) {
|
||||
callback(null, Object.keys(this.cache[model]).length);
|
||||
Memory.prototype.count = function count(model, callback, where) {
|
||||
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) {
|
||||
|
|
|
@ -15,7 +15,8 @@ exports.initialize = function initializeSchema(schema, callback) {
|
|||
});
|
||||
|
||||
schema.adapter = new MySQL(schema.client);
|
||||
process.nextTick(callback);
|
||||
schema.client.query('SET TIME_ZONE = "+04:00"', callback);
|
||||
// process.nextTick(callback);
|
||||
};
|
||||
|
||||
function MySQL(client) {
|
||||
|
@ -77,6 +78,19 @@ MySQL.prototype.toFields = function (model, data) {
|
|||
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) {
|
||||
if (prop.type.name === 'Number') return val;
|
||||
if (val === null) return 'NULL';
|
||||
|
@ -85,15 +99,7 @@ MySQL.prototype.toDatabase = function (prop, val) {
|
|||
if (!val.toUTCString) {
|
||||
val = new Date(val);
|
||||
}
|
||||
val = [
|
||||
val.getFullYear(),
|
||||
val.getMonth() + 1,
|
||||
val.getDate(),
|
||||
val.getHours(),
|
||||
val.getMinutes(),
|
||||
val.getSeconds()
|
||||
].join('-');
|
||||
return '"' + val + '"';
|
||||
return '"' + dateToMysql(val) + '"';
|
||||
}
|
||||
if (prop.type.name == "Boolean") return val ? 1 : 0;
|
||||
return this.client.escape(val.toString());
|
||||
|
@ -105,7 +111,9 @@ MySQL.prototype.fromDatabase = function (model, data) {
|
|||
Object.keys(data).forEach(function (key) {
|
||||
var val = data[key];
|
||||
if (props[key]) {
|
||||
// if (props[key])
|
||||
if (props[key].type.name === 'Date') {
|
||||
val = new Date(val.toString().replace(/GMT.*$/, 'GMT'));
|
||||
}
|
||||
}
|
||||
data[key] = val;
|
||||
});
|
||||
|
@ -165,7 +173,9 @@ MySQL.prototype.all = function all(model, filter, callback) {
|
|||
if (err) {
|
||||
return callback(err, []);
|
||||
}
|
||||
callback(null, data);
|
||||
callback(null, data.map(function (obj) {
|
||||
return self.fromDatabase(model, obj);
|
||||
}));
|
||||
}.bind(this));
|
||||
|
||||
return sql;
|
||||
|
@ -203,10 +213,26 @@ MySQL.prototype.destroyAll = function destroyAll(model, callback) {
|
|||
}.bind(this));
|
||||
};
|
||||
|
||||
MySQL.prototype.count = function count(model, callback) {
|
||||
this.query('SELECT count(*) as cnt FROM ' + model, function (err, res) {
|
||||
MySQL.prototype.count = function count(model, callback, where) {
|
||||
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);
|
||||
});
|
||||
|
||||
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) {
|
||||
|
|
|
@ -254,10 +254,21 @@ Neo4j.prototype.destroy = function destroy(model, id, callback) {
|
|||
Neo4j.prototype.all = function all(model, filter, callback) {
|
||||
this.client.queryNodeIndex(model, 'id:*', function (err, 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) {
|
||||
|
@ -285,6 +296,10 @@ function applyFilter(filter) {
|
|||
if (typeof value === 'string' && example && example.constructor.name === 'RegExp') {
|
||||
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
|
||||
return example == value;
|
||||
}
|
||||
|
@ -308,8 +323,8 @@ Neo4j.prototype.destroyAll = function destroyAll(model, callback) {
|
|||
}
|
||||
};
|
||||
|
||||
Neo4j.prototype.count = function count(model, callback) {
|
||||
this.all(model, null, function (err, collection) {
|
||||
Neo4j.prototype.count = function count(model, callback, conds) {
|
||||
this.all(model, {where: conds}, function (err, collection) {
|
||||
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) {
|
||||
if (val === null) return 'NULL';
|
||||
if (prop.type.name === 'Number') return val;
|
||||
|
@ -101,18 +117,10 @@ PG.prototype.toDatabase = function (prop, val) {
|
|||
if (!val.toUTCString) {
|
||||
val = new Date(val);
|
||||
}
|
||||
val = [
|
||||
val.getUTCFullYear(),
|
||||
val.getUTCMonth() + 1,
|
||||
val.getUTCDate()
|
||||
].join('-') + ' ' + [
|
||||
val.getUTCHours(),
|
||||
val.getUTCMinutes(),
|
||||
val.getUTCSeconds()
|
||||
].join(':');
|
||||
return escape(val);
|
||||
return escape(dateToPostgres(val));
|
||||
}
|
||||
return escape(val.toString());
|
||||
|
||||
};
|
||||
|
||||
PG.prototype.fromDatabase = function (model, data) {
|
||||
|
@ -161,7 +169,7 @@ PG.prototype.all = function all(model, filter, callback) {
|
|||
if (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));
|
||||
};
|
||||
|
||||
|
@ -171,7 +179,7 @@ PG.prototype.toFilter = function (model, filter) {
|
|||
}
|
||||
if (!filter) return '';
|
||||
var props = this._models[model].properties;
|
||||
var out='';
|
||||
var out = '';
|
||||
if (filter.where) {
|
||||
var fields = [];
|
||||
Object.keys(filter.where).forEach(function (key) {
|
||||
|
@ -188,9 +196,18 @@ PG.prototype.toFilter = function (model, filter) {
|
|||
}
|
||||
}.bind(this));
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -228,11 +245,26 @@ PG.prototype.destroyAll = function destroyAll(model, callback) {
|
|||
}.bind(this));
|
||||
};
|
||||
|
||||
PG.prototype.count = function count(model, callback) {
|
||||
this.query('SELECT count(*) as cnt FROM "' + model + '"', function (err, res) {
|
||||
PG.prototype.count = function count(model, callback, where) {
|
||||
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);
|
||||
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) {
|
||||
|
|
|
@ -366,13 +366,19 @@ BridgeToRedis.prototype.destroyAll = function destroyAll(model, callback) {
|
|||
}.bind(this));
|
||||
};
|
||||
|
||||
BridgeToRedis.prototype.count = function count(model, callback) {
|
||||
BridgeToRedis.prototype.count = function count(model, callback, where) {
|
||||
var keysQuery = model + ':*';
|
||||
var t1 = Date.now();
|
||||
this.client.keys(keysQuery, function (err, keys) {
|
||||
this.log('KEYS ' + keysQuery, t1);
|
||||
callback(err, err ? null : keys.length);
|
||||
}.bind(this));
|
||||
if (where && Object.keys(where).length) {
|
||||
this.all(model, {where: where}, function (err, data) {
|
||||
callback(err, err ? null : data.length);
|
||||
});
|
||||
} 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) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
},
|
||||
"main": "index.js",
|
||||
"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": [
|
||||
"node >= 0.4.0"
|
||||
|
|
|
@ -297,12 +297,15 @@ function testOrm(schema) {
|
|||
});
|
||||
});
|
||||
|
||||
var countOfposts;
|
||||
var countOfposts, countOfpostsFiltered;
|
||||
it('should fetch collection', function (test) {
|
||||
Post.all(function (err, posts) {
|
||||
countOfposts = posts.length;
|
||||
test.ok(countOfposts > 0);
|
||||
test.ok(posts[0] instanceof Post);
|
||||
countOfpostsFiltered = posts.filter(function (p) {
|
||||
return p.title === 'title';
|
||||
}).length;
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
|
@ -310,7 +313,10 @@ function testOrm(schema) {
|
|||
it('should fetch count of records in collection', function (test) {
|
||||
Post.count(function (err, 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);
|
||||
test.equal(posts.length, 5);
|
||||
dates.sort(numerically).forEach(function (d, i) {
|
||||
// fix inappropriated tz convert
|
||||
test.equal(posts[i].date.toString(), d.toString());
|
||||
});
|
||||
finished();
|
||||
|
|
Loading…
Reference in New Issue