Merge branch 'release/1.5.1' into production
This commit is contained in:
commit
929807a92c
|
@ -3,7 +3,8 @@ var ds = new DataSource('memory');
|
||||||
|
|
||||||
var Order = ds.createModel('Order', {
|
var Order = ds.createModel('Order', {
|
||||||
items: [String],
|
items: [String],
|
||||||
orderDate: Date
|
orderDate: Date,
|
||||||
|
qty: Number
|
||||||
});
|
});
|
||||||
|
|
||||||
var Customer = ds.createModel('Customer', {
|
var Customer = ds.createModel('Customer', {
|
||||||
|
@ -43,14 +44,17 @@ Customer.create({name: 'John'}, function (err, customer) {
|
||||||
Customer.hasMany(Order, {as: 'orders', foreignKey: 'customerId'});
|
Customer.hasMany(Order, {as: 'orders', foreignKey: 'customerId'});
|
||||||
|
|
||||||
Customer.create({name: 'Ray'}, function (err, customer) {
|
Customer.create({name: 'Ray'}, function (err, customer) {
|
||||||
Order.create({customerId: customer.id, orderDate: new Date()}, function (err, order) {
|
Order.create({customerId: customer.id, qty: 3, orderDate: new Date()}, function (err, order) {
|
||||||
order3 = order;
|
order3 = order;
|
||||||
customer.orders(console.log);
|
customer.orders(console.log);
|
||||||
customer.orders.create({orderDate: new Date()}, function (err, order) {
|
customer.orders.create({orderDate: new Date(), qty: 4}, function (err, order) {
|
||||||
console.log(order);
|
console.log(order);
|
||||||
Customer.include([customer], 'orders', function (err, results) {
|
Customer.include([customer], 'orders', function (err, results) {
|
||||||
console.log('Results: ', results);
|
console.log('Results: ', results);
|
||||||
});
|
});
|
||||||
|
customer.orders({where: {qty: 4}}, function(err, results) {
|
||||||
|
console.log('customer.orders', results);
|
||||||
|
});
|
||||||
customer.orders.findById(order3.id, console.log);
|
customer.orders.findById(order3.id, console.log);
|
||||||
customer.orders.destroy(order3.id, console.log);
|
customer.orders.destroy(order3.id, console.log);
|
||||||
});
|
});
|
||||||
|
|
|
@ -332,14 +332,31 @@ Memory.prototype.all = function all(model, filter, callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function applyFilter(filter) {
|
function applyFilter(filter) {
|
||||||
if (typeof filter.where === 'function') {
|
var where = filter.where;
|
||||||
return filter.where;
|
if (typeof where === 'function') {
|
||||||
|
return where;
|
||||||
}
|
}
|
||||||
var keys = Object.keys(filter.where);
|
var keys = Object.keys(where);
|
||||||
return function (obj) {
|
return function (obj) {
|
||||||
var pass = true;
|
var pass = true;
|
||||||
keys.forEach(function (key) {
|
keys.forEach(function (key) {
|
||||||
if (!test(filter.where[key], obj && obj[key])) {
|
if(key === 'and' || key === 'or') {
|
||||||
|
if(Array.isArray(where[key])) {
|
||||||
|
if(key === 'and') {
|
||||||
|
pass = where[key].every(function(cond) {
|
||||||
|
return applyFilter({where: cond})(obj);
|
||||||
|
});
|
||||||
|
return pass;
|
||||||
|
}
|
||||||
|
if(key === 'or') {
|
||||||
|
pass = where[key].some(function(cond) {
|
||||||
|
return applyFilter({where: cond})(obj);
|
||||||
|
});
|
||||||
|
return pass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!test(where[key], obj && obj[key])) {
|
||||||
pass = false;
|
pass = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -350,11 +367,14 @@ 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 example === 'undefined') return undefined;
|
if (example === undefined || value === undefined) {
|
||||||
if (typeof value === 'undefined') return undefined;
|
return undefined;
|
||||||
|
}
|
||||||
if (typeof example === 'object') {
|
if (typeof example === 'object') {
|
||||||
// ignore geo near filter
|
// ignore geo near filter
|
||||||
if (example.near) return true;
|
if (example.near) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (example.inq) {
|
if (example.inq) {
|
||||||
if (!value) return false;
|
if (!value) return false;
|
||||||
|
|
|
@ -359,7 +359,7 @@ function convertNullToNotFoundError(ctx, cb) {
|
||||||
|
|
||||||
var modelName = ctx.method.sharedClass.name;
|
var modelName = ctx.method.sharedClass.name;
|
||||||
var id = ctx.getArgByName('id');
|
var id = ctx.getArgByName('id');
|
||||||
var msg = 'Unkown "' + modelName + '" id "' + id + '".';
|
var msg = 'Unknown "' + modelName + '" id "' + id + '".';
|
||||||
var error = new Error(msg);
|
var error = new Error(msg);
|
||||||
error.statusCode = error.status = 404;
|
error.statusCode = error.status = 404;
|
||||||
cb(error);
|
cb(error);
|
||||||
|
|
|
@ -8,7 +8,7 @@ var ModelBaseClass = require('./model.js');
|
||||||
module.exports = Relation;
|
module.exports = Relation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Relations class
|
* Relations class. Use to define relationships between models.
|
||||||
*
|
*
|
||||||
* @class Relation
|
* @class Relation
|
||||||
*/
|
*/
|
||||||
|
@ -47,12 +47,25 @@ function lookupModel(models, modelName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare "hasMany" relation.
|
* Define a "one to many" relationship by specifying the model name
|
||||||
* Example:
|
|
||||||
* ```User.hasMany(Post, {as: 'posts', foreignKey: 'authorId'});```
|
|
||||||
*
|
*
|
||||||
|
* Examples:
|
||||||
|
* ```
|
||||||
|
* User.hasMany(Post, {as: 'posts', foreignKey: 'authorId'});
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* Book.hasMany(Chapter);
|
||||||
|
* ```
|
||||||
|
* Or, equivalently:
|
||||||
|
* ```
|
||||||
|
* Book.hasMany('chapters', {model: Chapter});
|
||||||
|
* ```
|
||||||
* @param {Relation} anotherClass Class to has many
|
* @param {Relation} anotherClass Class to has many
|
||||||
* @param {Object} params Configuration {as:, foreignKey:}
|
* @options {Object} parameters Configuration parameters
|
||||||
|
* @property {String} as
|
||||||
|
* @property {String} foreignKey Property name of foreign key field.
|
||||||
|
* @property {Object} model Model object
|
||||||
*/
|
*/
|
||||||
Relation.hasMany = function hasMany(anotherClass, params) {
|
Relation.hasMany = function hasMany(anotherClass, params) {
|
||||||
var thisClassName = this.modelName;
|
var thisClassName = this.modelName;
|
||||||
|
@ -218,9 +231,28 @@ Relation.hasMany = function hasMany(anotherClass, params) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare "belongsTo" relation.
|
* Declare "belongsTo" relation that sets up a one-to-one connection with another model, such that each
|
||||||
|
* instance of the declaring model "belongs to" one instance of the other model.
|
||||||
*
|
*
|
||||||
* **Examples**
|
* For example, if an application includes users and posts, and each post can be written by exactly one user.
|
||||||
|
* The following code specifies that `Post` has a reference called `author` to the `User` model via the `userId` property of `Post`
|
||||||
|
* as the foreign key.
|
||||||
|
* ```
|
||||||
|
* Post.belongsTo(User, {as: 'author', foreignKey: 'userId'});
|
||||||
|
* ```
|
||||||
|
* You can then access the author in one of the following styles.
|
||||||
|
* Get the User object for the post author asynchronously:
|
||||||
|
* ```
|
||||||
|
* post.author(callback);
|
||||||
|
* ```
|
||||||
|
* Get the User object for the post author synchronously:
|
||||||
|
* ```
|
||||||
|
* post.author();
|
||||||
|
* Set the author to be the given user:
|
||||||
|
* ```
|
||||||
|
* post.author(user)
|
||||||
|
* ```
|
||||||
|
* Examples:
|
||||||
*
|
*
|
||||||
* Suppose the model Post has a *belongsTo* relationship with User (the author of the post). You could declare it this way:
|
* Suppose the model Post has a *belongsTo* relationship with User (the author of the post). You could declare it this way:
|
||||||
* ```js
|
* ```js
|
||||||
|
@ -244,7 +276,9 @@ Relation.hasMany = function hasMany(anotherClass, params) {
|
||||||
* This optional parameter default value is false, so the related object will be loaded from cache if available.
|
* This optional parameter default value is false, so the related object will be loaded from cache if available.
|
||||||
*
|
*
|
||||||
* @param {Class} anotherClass Class to belong
|
* @param {Class} anotherClass Class to belong
|
||||||
* @param {Object} params Configuration {as: 'propertyName', foreignKey: 'keyName'}
|
* @param {Object} Parameters Configuration parameters
|
||||||
|
* @property {String} as Can be 'propertyName'
|
||||||
|
* @property {String} foreignKey Name of foreign key property.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Relation.belongsTo = function (anotherClass, params) {
|
Relation.belongsTo = function (anotherClass, params) {
|
||||||
|
@ -389,15 +423,34 @@ Relation.belongsTo = function (anotherClass, params) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Many-to-many relation
|
* A hasAndBelongsToMany relation creates a direct many-to-many connection with another model, with no intervening model.
|
||||||
*
|
* For example, if your application includes users and groups, with each group having many users and each user appearing
|
||||||
* For example, this creates connection model 'PostTag':
|
* in many groups, you could declare the models this way:
|
||||||
* ```js
|
* ```
|
||||||
* Post.hasAndBelongsToMany('tags');
|
* User.hasAndBelongsToMany('groups', {model: Group, foreignKey: 'groupId'});
|
||||||
* ```
|
* ```
|
||||||
|
* Then, to get the groups to which the user belongs:
|
||||||
|
* ```
|
||||||
|
* user.groups(callback);
|
||||||
|
* ```
|
||||||
|
* Create a new group and connect it with the user:
|
||||||
|
* ```
|
||||||
|
* user.groups.create(data, callback);
|
||||||
|
* ```
|
||||||
|
* Connect an existing group with the user:
|
||||||
|
* ```
|
||||||
|
* user.groups.add(group, callback);
|
||||||
|
* ```
|
||||||
|
* Remove the user from the group:
|
||||||
|
* ```
|
||||||
|
* user.groups.remove(group, callback);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
* @param {String|Function} anotherClass - target class to hasAndBelongsToMany or name of
|
* @param {String|Function} anotherClass - target class to hasAndBelongsToMany or name of
|
||||||
* the relation
|
* the relation
|
||||||
* @param {Object} params - configuration {as: String, foreignKey: *, model: ModelClass}
|
* @options {Object} params - configuration {as: String, foreignKey: *, model: ModelClass}
|
||||||
|
* @property {Object} model Model name
|
||||||
|
* @property {String} foreignKey Property name of foreign key field.
|
||||||
*/
|
*/
|
||||||
Relation.hasAndBelongsToMany = function hasAndBelongsToMany(anotherClass, params) {
|
Relation.hasAndBelongsToMany = function hasAndBelongsToMany(anotherClass, params) {
|
||||||
params = params || {};
|
params = params || {};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "loopback-datasource-juggler",
|
"name": "loopback-datasource-juggler",
|
||||||
"version": "1.5.0",
|
"version": "1.5.1",
|
||||||
"description": "LoopBack DataSoure Juggler",
|
"description": "LoopBack DataSoure Juggler",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"StrongLoop",
|
"StrongLoop",
|
||||||
|
|
|
@ -131,6 +131,50 @@ describe('basic-querying', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support "and" operator that is satisfied', function (done) {
|
||||||
|
User.find({where: {and: [
|
||||||
|
{name: 'John Lennon'},
|
||||||
|
{role: 'lead'}
|
||||||
|
]}}, function (err, users) {
|
||||||
|
should.not.exist(err);
|
||||||
|
users.should.have.property('length', 1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support "and" operator that is not satisfied', function (done) {
|
||||||
|
User.find({where: {and: [
|
||||||
|
{name: 'John Lennon'},
|
||||||
|
{role: 'member'}
|
||||||
|
]}}, function (err, users) {
|
||||||
|
should.not.exist(err);
|
||||||
|
users.should.have.property('length', 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support "or" that is satisfied', function (done) {
|
||||||
|
User.find({where: {or: [
|
||||||
|
{name: 'John Lennon'},
|
||||||
|
{role: 'lead'}
|
||||||
|
]}}, function (err, users) {
|
||||||
|
should.not.exist(err);
|
||||||
|
users.should.have.property('length', 2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should support "or" operator that is not satisfied', function (done) {
|
||||||
|
User.find({where: {or: [
|
||||||
|
{name: 'XYZ'},
|
||||||
|
{role: 'Hello1'}
|
||||||
|
]}}, function (err, users) {
|
||||||
|
should.not.exist(err);
|
||||||
|
users.should.have.property('length', 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('should only include fields as specified', function (done) {
|
it('should only include fields as specified', function (done) {
|
||||||
var remaining = 0;
|
var remaining = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue