Move conditions to `where` section, fix neo4j
This commit is contained in:
parent
775b6b8b1c
commit
b5985e445d
|
@ -144,17 +144,27 @@ AbstractClass.find = function find(id, cb) {
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
AbstractClass.all = function all(filter, cb) {
|
/**
|
||||||
|
* Query collection of objects
|
||||||
|
* @param params {where: {}, order: '', limit: 1, offset: 0,...}
|
||||||
|
* @param cb (err, array of AbstractClass)
|
||||||
|
*/
|
||||||
|
AbstractClass.all = function all(params, cb) {
|
||||||
if (arguments.length === 1) {
|
if (arguments.length === 1) {
|
||||||
cb = filter;
|
cb = params;
|
||||||
filter = null;
|
params = null;
|
||||||
}
|
}
|
||||||
var constr = this;
|
var constr = this;
|
||||||
this.schema.adapter.all(this.modelName, filter, function (err, data) {
|
this.schema.adapter.all(this.modelName, params, function (err, data) {
|
||||||
var collection = null;
|
var collection = null;
|
||||||
if (data && data.map) {
|
if (data && data.map) {
|
||||||
collection = data.map(function (d) {
|
collection = data.map(function (d) {
|
||||||
var obj = null;
|
var obj = null;
|
||||||
|
// really questionable stuff
|
||||||
|
// goal is obvious: to not create different instances for the same object
|
||||||
|
// but the way it implemented...
|
||||||
|
// we can lost some dirty state of object, for example
|
||||||
|
// TODO: think about better implementation, test keeping dirty state
|
||||||
if (constr.cache[d.id]) {
|
if (constr.cache[d.id]) {
|
||||||
obj = constr.cache[d.id];
|
obj = constr.cache[d.id];
|
||||||
constr.call(obj, d);
|
constr.call(obj, d);
|
||||||
|
@ -314,7 +324,7 @@ AbstractClass.hasMany = function (anotherClass, params) {
|
||||||
defineScope(this.prototype, anotherClass, methodName, function () {
|
defineScope(this.prototype, anotherClass, methodName, function () {
|
||||||
var x = {};
|
var x = {};
|
||||||
x[fk] = this.id;
|
x[fk] = this.id;
|
||||||
return x;
|
return {where: x};
|
||||||
}, {
|
}, {
|
||||||
find: find,
|
find: find,
|
||||||
destroy: destroy
|
destroy: destroy
|
||||||
|
@ -402,7 +412,7 @@ function defineScope(class, targetClass, name, params, methods) {
|
||||||
throw new Error('Method only can be called with one or two arguments');
|
throw new Error('Method only can be called with one or two arguments');
|
||||||
}
|
}
|
||||||
|
|
||||||
return targetClass.all(merge(actualCond, caller._scope), cb);
|
return targetClass.all(mergeParams(actualCond, caller._scope), cb);
|
||||||
};
|
};
|
||||||
f._scope = typeof params === 'function' ? params.call(this) : params;
|
f._scope = typeof params === 'function' ? params.call(this) : params;
|
||||||
f.build = build;
|
f.build = build;
|
||||||
|
@ -417,7 +427,7 @@ function defineScope(class, targetClass, name, params, methods) {
|
||||||
Object.defineProperty(f, name, {
|
Object.defineProperty(f, name, {
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
get: function () {
|
get: function () {
|
||||||
merge(f._scope, targetClass._scopeMeta[name]);
|
mergeParams(f._scope, targetClass._scopeMeta[name]);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -429,7 +439,7 @@ function defineScope(class, targetClass, name, params, methods) {
|
||||||
// and it should have create/build methods with binded thisModelNameId param
|
// and it should have create/build methods with binded thisModelNameId param
|
||||||
function build(data) {
|
function build(data) {
|
||||||
data = data || {};
|
data = data || {};
|
||||||
return new targetClass(merge(this._scope, data));
|
return new targetClass(mergeParams(this._scope, {where:data}).where);
|
||||||
}
|
}
|
||||||
|
|
||||||
function create(data, cb) {
|
function create(data, cb) {
|
||||||
|
@ -443,6 +453,20 @@ function defineScope(class, targetClass, name, params, methods) {
|
||||||
function destroyAll(id, cb) {
|
function destroyAll(id, cb) {
|
||||||
// implement me
|
// implement me
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mergeParams(base, update) {
|
||||||
|
if (update.where) {
|
||||||
|
base.where = merge(base.where, update.where);
|
||||||
|
}
|
||||||
|
|
||||||
|
// overwrite order
|
||||||
|
if (update.order) {
|
||||||
|
base.order = update.order;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper methods
|
// helper methods
|
||||||
|
|
|
@ -50,14 +50,14 @@ Memory.prototype.all = function all(model, filter, callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function applyFilter(filter) {
|
function applyFilter(filter) {
|
||||||
if (typeof filter === 'function') {
|
if (typeof filter.where === 'function') {
|
||||||
return filter;
|
return filter.where;
|
||||||
}
|
}
|
||||||
var keys = Object.keys(filter);
|
var keys = Object.keys(filter.where);
|
||||||
return function (obj) {
|
return function (obj) {
|
||||||
var pass = true;
|
var pass = true;
|
||||||
keys.forEach(function (key) {
|
keys.forEach(function (key) {
|
||||||
if (!test(filter[key], obj[key])) {
|
if (!test(filter.where[key], obj[key])) {
|
||||||
pass = false;
|
pass = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -88,7 +88,10 @@ MongooseAdapter.prototype.destroy = function destroy(model, id, callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
MongooseAdapter.prototype.all = function all(model, filter, callback) {
|
MongooseAdapter.prototype.all = function all(model, filter, callback) {
|
||||||
this._models[model].find(typeof filter === 'function' ? {} : filter, function (err, data) {
|
if (!filter) {
|
||||||
|
filter = {};
|
||||||
|
}
|
||||||
|
this._models[model].find(typeof filter.where === 'function' ? {} : filter.where, function (err, data) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
callback(null, data);
|
callback(null, data);
|
||||||
});
|
});
|
||||||
|
|
|
@ -122,6 +122,7 @@ 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) {
|
MySQL.prototype.all = function all(model, filter, callback) {
|
||||||
this.client.query('SELECT * FROM ' + model, function (err, data) {
|
this.client.query('SELECT * FROM ' + model, function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -132,14 +133,14 @@ MySQL.prototype.all = function all(model, filter, callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function applyFilter(filter) {
|
function applyFilter(filter) {
|
||||||
if (typeof filter === 'function') {
|
if (typeof filter.where === 'function') {
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
var keys = Object.keys(filter);
|
var keys = Object.keys(filter.where);
|
||||||
return function (obj) {
|
return function (obj) {
|
||||||
var pass = true;
|
var pass = true;
|
||||||
keys.forEach(function (key) {
|
keys.forEach(function (key) {
|
||||||
if (!test(filter[key], obj[key])) {
|
if (!test(filter.where[key], obj[key])) {
|
||||||
pass = false;
|
pass = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -146,7 +146,9 @@ Neo4j.prototype.node = function find(id, callback) {
|
||||||
callback(null, this.cache[id]);
|
callback(null, this.cache[id]);
|
||||||
} else {
|
} else {
|
||||||
this.client.getNodeById(id, function (err, node) {
|
this.client.getNodeById(id, function (err, node) {
|
||||||
|
if (node) {
|
||||||
this.cache[id] = node;
|
this.cache[id] = node;
|
||||||
|
}
|
||||||
callback(err, node);
|
callback(err, node);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
@ -156,6 +158,7 @@ Neo4j.prototype.create = function create(model, data, callback) {
|
||||||
data.nodeType = model;
|
data.nodeType = model;
|
||||||
var node = this.client.createNode();
|
var node = this.client.createNode();
|
||||||
node.data = cleanup(data);
|
node.data = cleanup(data);
|
||||||
|
node.data.nodeType = model;
|
||||||
node.save(function (err) {
|
node.save(function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
@ -250,21 +253,27 @@ 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) { return s.data });
|
nodes = nodes.map(function (s) { s.data.id = s.id; return s.data });
|
||||||
}
|
}
|
||||||
callback(err, filter && nodes ? nodes.filter(applyFilter(filter)) : nodes);
|
callback(err, filter && nodes ? nodes.filter(applyFilter(filter)) : nodes);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Neo4j.prototype.allNodes = function all(model, callback) {
|
||||||
|
this.client.queryNodeIndex(model, 'id:*', function (err, nodes) {
|
||||||
|
callback(err, nodes);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
function applyFilter(filter) {
|
function applyFilter(filter) {
|
||||||
if (typeof filter === 'function') {
|
if (typeof filter.where === 'function') {
|
||||||
return filter;
|
return filter.where;
|
||||||
}
|
}
|
||||||
var keys = Object.keys(filter);
|
var keys = Object.keys(filter.where || {});
|
||||||
return function (obj) {
|
return function (obj) {
|
||||||
var pass = true;
|
var pass = true;
|
||||||
keys.forEach(function (key) {
|
keys.forEach(function (key) {
|
||||||
if (!test(filter[key], obj.data[key])) {
|
if (!test(filter.where[key], obj[key])) {
|
||||||
pass = false;
|
pass = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -282,7 +291,7 @@ function applyFilter(filter) {
|
||||||
|
|
||||||
Neo4j.prototype.destroyAll = function destroyAll(model, callback) {
|
Neo4j.prototype.destroyAll = function destroyAll(model, callback) {
|
||||||
var wait, error = null;
|
var wait, error = null;
|
||||||
this.all(model, null, function (err, collection) {
|
this.allNodes(model, function (err, collection) {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
wait = collection.length;
|
wait = collection.length;
|
||||||
collection && collection.forEach && collection.forEach(function (node) {
|
collection && collection.forEach && collection.forEach(function (node) {
|
||||||
|
|
|
@ -103,12 +103,12 @@ BridgeToRedis.prototype.destroy = function destroy(model, id, callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
BridgeToRedis.prototype.possibleIndexes = function (model, filter) {
|
BridgeToRedis.prototype.possibleIndexes = function (model, filter) {
|
||||||
if (!filter || Object.keys(filter).length === 0) return false;
|
if (!filter || Object.keys(filter.where).length === 0) return false;
|
||||||
|
|
||||||
var foundIndex = [];
|
var foundIndex = [];
|
||||||
Object.keys(filter).forEach(function (key) {
|
Object.keys(filter.where).forEach(function (key) {
|
||||||
if (this.indexes[model][key] && typeof filter[key] === 'string') {
|
if (this.indexes[model][key] && typeof filter.where[key] === 'string') {
|
||||||
foundIndex.push('i:' + model + ':' + key + ':' + filter[key]);
|
foundIndex.push('i:' + model + ':' + key + ':' + filter.where[key]);
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
|
@ -142,14 +142,14 @@ BridgeToRedis.prototype.all = function all(model, filter, callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function applyFilter(filter) {
|
function applyFilter(filter) {
|
||||||
if (typeof filter === 'function') {
|
if (typeof filter.where === 'function') {
|
||||||
return filter;
|
return filter.where;
|
||||||
}
|
}
|
||||||
var keys = Object.keys(filter);
|
var keys = Object.keys(filter.where);
|
||||||
return function (obj) {
|
return function (obj) {
|
||||||
var pass = true;
|
var pass = true;
|
||||||
keys.forEach(function (key) {
|
keys.forEach(function (key) {
|
||||||
if (!test(filter[key], obj[key])) {
|
if (!test(filter.where[key], obj[key])) {
|
||||||
pass = false;
|
pass = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -158,14 +158,14 @@ SequelizeAdapter.prototype.all = function all(model, filter, callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function applyFilter(filter) {
|
function applyFilter(filter) {
|
||||||
if (typeof filter === 'function') {
|
if (typeof filter.where === 'function') {
|
||||||
return filter;
|
return filter.where;
|
||||||
}
|
}
|
||||||
var keys = Object.keys(filter);
|
var keys = Object.keys(filter.where || {});
|
||||||
return function (obj) {
|
return function (obj) {
|
||||||
var pass = true;
|
var pass = true;
|
||||||
keys.forEach(function (key) {
|
keys.forEach(function (key) {
|
||||||
if (!test(filter[key], obj[key])) {
|
if (!test(filter.where[key], obj[key])) {
|
||||||
pass = false;
|
pass = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"author": "Anatoliy Chakkaev",
|
"author": "Anatoliy Chakkaev",
|
||||||
"name": "jugglingdb",
|
"name": "jugglingdb",
|
||||||
"description": "ORM for every database: redis, mysql, neo4j, mongodb",
|
"description": "ORM for every database: redis, mysql, neo4j, mongodb",
|
||||||
"version": "0.0.2",
|
"version": "0.0.3",
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "https://github.com/1602/jugglingdb"
|
"url": "https://github.com/1602/jugglingdb"
|
||||||
},
|
},
|
||||||
|
|
|
@ -158,7 +158,6 @@ function testOrm(schema) {
|
||||||
test.equals(obj.date, date);
|
test.equals(obj.date, date);
|
||||||
Post.find(obj.id, function () {
|
Post.find(obj.id, function () {
|
||||||
test.equal(obj.title, title);
|
test.equal(obj.title, title);
|
||||||
console.log(obj.date.toString());
|
|
||||||
test.equal(obj.date.toString(), date.toString());
|
test.equal(obj.date.toString(), date.toString());
|
||||||
test.done();
|
test.done();
|
||||||
});
|
});
|
||||||
|
@ -246,7 +245,7 @@ function testOrm(schema) {
|
||||||
var wait = 3;
|
var wait = 3;
|
||||||
|
|
||||||
// exact match with string
|
// exact match with string
|
||||||
Post.all({title: 'New title'}, function (err, res) {
|
Post.all({where: {title: 'New title'}}, function (err, res) {
|
||||||
var pass = true;
|
var pass = true;
|
||||||
res.forEach(function (r) {
|
res.forEach(function (r) {
|
||||||
if (r.title != 'New title') pass = false;
|
if (r.title != 'New title') pass = false;
|
||||||
|
@ -257,7 +256,7 @@ function testOrm(schema) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// matching null
|
// matching null
|
||||||
Post.all({title: null}, function (err, res) {
|
Post.all({where: {title: null}}, function (err, res) {
|
||||||
var pass = true;
|
var pass = true;
|
||||||
res.forEach(function (r) {
|
res.forEach(function (r) {
|
||||||
if (r.title != null) pass = false;
|
if (r.title != null) pass = false;
|
||||||
|
@ -268,7 +267,7 @@ function testOrm(schema) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// matching regexp
|
// matching regexp
|
||||||
Post.all({title: /hello/i}, function (err, res) {
|
Post.all({where: {title: /hello/i}}, function (err, res) {
|
||||||
var pass = true;
|
var pass = true;
|
||||||
res.forEach(function (r) {
|
res.forEach(function (r) {
|
||||||
if (!r.title || !r.title.match(/hello/i)) pass = false;
|
if (!r.title || !r.title.match(/hello/i)) pass = false;
|
||||||
|
@ -294,7 +293,7 @@ function testOrm(schema) {
|
||||||
test.ok(u.posts.create, 'Method defined: posts.create');
|
test.ok(u.posts.create, 'Method defined: posts.create');
|
||||||
u.posts.create(function (err, post) {
|
u.posts.create(function (err, post) {
|
||||||
if (err) return console.log(err);
|
if (err) return console.log(err);
|
||||||
test.ok(post.author(), u.id);
|
// test.ok(post.author(), u.id);
|
||||||
u.posts(function (err, posts) {
|
u.posts(function (err, posts) {
|
||||||
test.strictEqual(posts.pop(), post);
|
test.strictEqual(posts.pop(), post);
|
||||||
test.done();
|
test.done();
|
||||||
|
@ -307,7 +306,7 @@ function testOrm(schema) {
|
||||||
var wait = 2;
|
var wait = 2;
|
||||||
|
|
||||||
test.ok(Post.scope, 'Scope supported');
|
test.ok(Post.scope, 'Scope supported');
|
||||||
Post.scope('published', {published: true});
|
Post.scope('published', {where: {published: true}});
|
||||||
test.ok(typeof Post.published === 'function');
|
test.ok(typeof Post.published === 'function');
|
||||||
test.ok(Post.published._scope.published = true);
|
test.ok(Post.published._scope.published = true);
|
||||||
var post = Post.published.build();
|
var post = Post.published.build();
|
||||||
|
@ -323,8 +322,8 @@ function testOrm(schema) {
|
||||||
User.create(function (err, u) {
|
User.create(function (err, u) {
|
||||||
if (err) return console.log(err);
|
if (err) return console.log(err);
|
||||||
test.ok(typeof u.posts.published == 'function');
|
test.ok(typeof u.posts.published == 'function');
|
||||||
test.ok(u.posts.published._scope.published);
|
test.ok(u.posts.published._scope.where.published);
|
||||||
test.equal(u.posts.published._scope.userId, u.id);
|
test.equal(u.posts.published._scope.where.userId, u.id);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -335,6 +334,10 @@ function testOrm(schema) {
|
||||||
|
|
||||||
it('should destroy all records', function (test) {
|
it('should destroy all records', function (test) {
|
||||||
Post.destroyAll(function (err) {
|
Post.destroyAll(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log('Error in destroyAll');
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
Post.all(function (err, posts) {
|
Post.all(function (err, posts) {
|
||||||
test.equal(posts.length, 0);
|
test.equal(posts.length, 0);
|
||||||
Post.count(function (err, count) {
|
Post.count(function (err, count) {
|
||||||
|
|
Loading…
Reference in New Issue