Reformat the code
This commit is contained in:
parent
58a06272c3
commit
2b8c1ebaee
|
@ -4,12 +4,14 @@ var modelBuilder = new ModelBuilder();
|
||||||
var Post = modelBuilder.define('Post', {
|
var Post = modelBuilder.define('Post', {
|
||||||
title: { type: String, length: 255 },
|
title: { type: String, length: 255 },
|
||||||
content: { type: ModelBuilder.Text },
|
content: { type: ModelBuilder.Text },
|
||||||
date: { type: Date, default: function () { return new Date;} },
|
date: { type: Date, default: function () {
|
||||||
|
return new Date();
|
||||||
|
} },
|
||||||
timestamp: { type: Number, default: Date.now },
|
timestamp: { type: Number, default: Date.now },
|
||||||
published: { type: Boolean, default: false, index: true }
|
published: { type: Boolean, default: false, index: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
// simplier way to describe model
|
// simpler way to describe model
|
||||||
var User = modelBuilder.define('User', {
|
var User = modelBuilder.define('User', {
|
||||||
name: String,
|
name: String,
|
||||||
bio: ModelBuilder.Text,
|
bio: ModelBuilder.Text,
|
||||||
|
|
|
@ -55,8 +55,8 @@ var user2 = new User({name: 'Smith'});
|
||||||
user2.save(function (err) {
|
user2.save(function (err) {
|
||||||
console.log(user2);
|
console.log(user2);
|
||||||
var post = user2.posts.build({title: 'Hello world'});
|
var post = user2.posts.build({title: 'Hello world'});
|
||||||
post.save(function(err, data) {
|
post.save(function (err, data) {
|
||||||
console.log(err ? err: data);
|
console.log(err ? err : data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ User.create({name: 'Ray'}, function (err, data) {
|
||||||
});
|
});
|
||||||
|
|
||||||
User.scope('minors', {age: {le: 16}});
|
User.scope('minors', {age: {le: 16}});
|
||||||
User.minors(function(err, kids) {
|
User.minors(function (err, kids) {
|
||||||
console.log('Kids: ', kids);
|
console.log('Kids: ', kids);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -87,10 +87,10 @@ var Article = ds.define('Article', {title: String});
|
||||||
var Tag = ds.define('Tag', {name: String});
|
var Tag = ds.define('Tag', {name: String});
|
||||||
Article.hasAndBelongsToMany('tags');
|
Article.hasAndBelongsToMany('tags');
|
||||||
|
|
||||||
Article.create(function(e, article) {
|
Article.create(function (e, article) {
|
||||||
article.tags.create({name: 'popular'}, function (err, data) {
|
article.tags.create({name: 'popular'}, function (err, data) {
|
||||||
Article.findOne(function(e, article) {
|
Article.findOne(function (e, article) {
|
||||||
article.tags(function(e, tags) {
|
article.tags(function (e, tags) {
|
||||||
console.log(tags);
|
console.log(tags);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,7 +9,7 @@ var path = require('path'),
|
||||||
*/
|
*/
|
||||||
function loadSchemasSync(schemaFile, dataSource) {
|
function loadSchemasSync(schemaFile, dataSource) {
|
||||||
// Set up the data source
|
// Set up the data source
|
||||||
if(!dataSource) {
|
if (!dataSource) {
|
||||||
dataSource = new DataSource('memory');
|
dataSource = new DataSource('memory');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,18 @@ var User = modelBuilder.define('User', {
|
||||||
zipCode: String,
|
zipCode: String,
|
||||||
country: String
|
country: String
|
||||||
},
|
},
|
||||||
emails: [{
|
emails: [
|
||||||
|
{
|
||||||
label: String,
|
label: String,
|
||||||
email: String
|
email: String
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
friends: [String]
|
friends: [String]
|
||||||
});
|
});
|
||||||
|
|
||||||
var user = new User({name: 'Joe', age: 20, address: {street: '123 Main St', 'city': 'San Jose', state: 'CA'},
|
var user = new User({name: 'Joe', age: 20, address: {street: '123 Main St', 'city': 'San Jose', state: 'CA'},
|
||||||
emails: [{label: 'work', email: 'xyz@sample.com'}],
|
emails: [
|
||||||
|
{label: 'work', email: 'xyz@sample.com'}
|
||||||
|
],
|
||||||
friends: ['John', 'Mary']});
|
friends: ['John', 'Mary']});
|
||||||
console.log(user.toObject());
|
console.log(user.toObject());
|
||||||
|
|
|
@ -24,15 +24,14 @@ 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, orderDate: new Date()}, function (err, order) {
|
||||||
customer.orders(console.log);
|
customer.orders(console.log);
|
||||||
customer.orders.create({orderDate: new Date()}, function(err, order) {
|
customer.orders.create({orderDate: new Date()}, 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.findById('2', console.log);
|
customer.orders.findById('2', console.log);
|
||||||
|
@ -41,7 +40,6 @@ Customer.create({name: 'Ray'}, function (err, customer) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var Physician = ds.createModel('Physician', {
|
var Physician = ds.createModel('Physician', {
|
||||||
name: String
|
name: String
|
||||||
});
|
});
|
||||||
|
@ -72,7 +70,6 @@ Physician.create({name: 'Smith'}, function (err, physician) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var Assembly = ds.createModel('Assembly', {
|
var Assembly = ds.createModel('Assembly', {
|
||||||
name: String
|
name: String
|
||||||
});
|
});
|
||||||
|
@ -86,7 +83,7 @@ Part.hasAndBelongsToMany(Assembly);
|
||||||
|
|
||||||
Assembly.create({name: 'car'}, function (err, assembly) {
|
Assembly.create({name: 'car'}, function (err, assembly) {
|
||||||
Part.create({partNumber: 'engine'}, function (err, part) {
|
Part.create({partNumber: 'engine'}, function (err, part) {
|
||||||
assembly.parts.add(part, function(err) {
|
assembly.parts.add(part, function (err) {
|
||||||
assembly.parts(console.log);
|
assembly.parts(console.log);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -27,15 +27,14 @@ Connector.prototype.execute = function (command, params, callback) {
|
||||||
throw new Error('query method should be declared in connector');
|
throw new Error('query method should be declared in connector');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up the data source by model name
|
* Look up the data source by model name
|
||||||
* @param {String} model The model name
|
* @param {String} model The model name
|
||||||
* @returns {DataSource} The data source
|
* @returns {DataSource} The data source
|
||||||
*/
|
*/
|
||||||
Connector.prototype.getDataSource = function(model) {
|
Connector.prototype.getDataSource = function (model) {
|
||||||
var m = this._models[model];
|
var m = this._models[model];
|
||||||
if(!m) {
|
if (!m) {
|
||||||
console.trace('Model not found: ' + model);
|
console.trace('Model not found: ' + model);
|
||||||
}
|
}
|
||||||
return m && m.model.dataSource;
|
return m && m.model.dataSource;
|
||||||
|
@ -59,7 +58,6 @@ Connector.prototype.idNames = function (model) {
|
||||||
return this.getDataSource(model).idNames(model);
|
return this.getDataSource(model).idNames(model);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the id index (sequence number, starting from 1)
|
* Get the id index (sequence number, starting from 1)
|
||||||
* @param {String} model The model name
|
* @param {String} model The model name
|
||||||
|
@ -68,8 +66,8 @@ Connector.prototype.idNames = function (model) {
|
||||||
*/
|
*/
|
||||||
Connector.prototype.id = function (model, prop) {
|
Connector.prototype.id = function (model, prop) {
|
||||||
var p = this._models[model].properties[prop];
|
var p = this._models[model].properties[prop];
|
||||||
if(!p) {
|
if (!p) {
|
||||||
console.trace('Property not found: ' + model +'.' + prop);
|
console.trace('Property not found: ' + model + '.' + prop);
|
||||||
}
|
}
|
||||||
return p.id;
|
return p.id;
|
||||||
};
|
};
|
||||||
|
@ -109,7 +107,7 @@ Connector.prototype.disconnect = function disconnect(cb) {
|
||||||
* @returns {*} The id value
|
* @returns {*} The id value
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Connector.prototype.getIdValue = function(model, data) {
|
Connector.prototype.getIdValue = function (model, data) {
|
||||||
return data && data[this.idName(model)];
|
return data && data[this.idName(model)];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,12 +118,16 @@ Connector.prototype.getIdValue = function(model, data) {
|
||||||
* @param {*} value The id value
|
* @param {*} value The id value
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Connector.prototype.setIdValue = function(model, data, value) {
|
Connector.prototype.setIdValue = function (model, data, value) {
|
||||||
if(data) {
|
if (data) {
|
||||||
data[this.idName(model)] = value;
|
data[this.idName(model)] = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Connector.prototype.getType = function () {
|
||||||
|
return this.type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,16 +15,22 @@ function CradleAdapter(client) {
|
||||||
|
|
||||||
function createdbif(client, callback) {
|
function createdbif(client, callback) {
|
||||||
client.exists(function (err, exists) {
|
client.exists(function (err, exists) {
|
||||||
if(err) callback(err);
|
if (err) callback(err);
|
||||||
if (!exists) { client.create(function() { callback(); }); }
|
if (!exists) {
|
||||||
else { callback(); }
|
client.create(function () {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function naturalize(data, model) {
|
function naturalize(data, model) {
|
||||||
data.nature = model;
|
data.nature = model;
|
||||||
//TODO: maybe this is not a really good idea
|
//TODO: maybe this is not a really good idea
|
||||||
if(data.date) data.date = data.date.toString();
|
if (data.date) data.date = data.date.toString();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
function idealize(data) {
|
function idealize(data) {
|
||||||
|
@ -36,13 +42,13 @@ function stringify(data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function errorHandler(callback, func) {
|
function errorHandler(callback, func) {
|
||||||
return function(err, res) {
|
return function (err, res) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('cradle', err);
|
console.log('cradle', err);
|
||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
if(func) {
|
if (func) {
|
||||||
func(res, function(res) {
|
func(res, function (res) {
|
||||||
callback(null, res);
|
callback(null, res);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,10 +59,10 @@ function errorHandler(callback, func) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function synchronize(functions, args, callback) {
|
function synchronize(functions, args, callback) {
|
||||||
if(functions.length === 0) callback();
|
if (functions.length === 0) callback();
|
||||||
if(functions.length > 0 && args.length === functions.length) {
|
if (functions.length > 0 && args.length === functions.length) {
|
||||||
functions[0](args[0][0], args[0][1], function(err, res) {
|
functions[0](args[0][0], args[0][1], function (err, res) {
|
||||||
if(err) callback(err);
|
if (err) callback(err);
|
||||||
functions.splice(0, 1);
|
functions.splice(0, 1);
|
||||||
args.splice(0, 1);
|
args.splice(0, 1);
|
||||||
synchronize(functions, args, callback);
|
synchronize(functions, args, callback);
|
||||||
|
@ -98,9 +104,9 @@ function literally(a, b) {
|
||||||
|
|
||||||
function filtering(res, model, filter, instance) {
|
function filtering(res, model, filter, instance) {
|
||||||
|
|
||||||
if(model) {
|
if (model) {
|
||||||
if(filter == null) filter = {};
|
if (filter == null) filter = {};
|
||||||
if(filter.where == null) filter.where = {};
|
if (filter.where == null) filter.where = {};
|
||||||
filter.where.nature = model;
|
filter.where.nature = model;
|
||||||
}
|
}
|
||||||
// do we need some filtration?
|
// do we need some filtration?
|
||||||
|
@ -142,7 +148,7 @@ function filtering(res, model, filter, instance) {
|
||||||
/**
|
/**
|
||||||
* Connection/Disconnection
|
* Connection/Disconnection
|
||||||
*/
|
*/
|
||||||
exports.initialize = function(dataSource, callback) {
|
exports.initialize = function (dataSource, callback) {
|
||||||
if (!cradle) return;
|
if (!cradle) return;
|
||||||
|
|
||||||
// when using cradle if we dont wait for the dataSource to be connected, the models fails to load correctly.
|
// when using cradle if we dont wait for the dataSource to be connected, the models fails to load correctly.
|
||||||
|
@ -168,37 +174,37 @@ exports.initialize = function(dataSource, callback) {
|
||||||
dataSource.settings.database = database;
|
dataSource.settings.database = database;
|
||||||
dataSource.settings.options = options;
|
dataSource.settings.options = options;
|
||||||
}
|
}
|
||||||
dataSource.client = new(cradle.Connection)(dataSource.settings.host, dataSource.settings.port,dataSource.settings.options).database(dataSource.settings.database);
|
dataSource.client = new (cradle.Connection)(dataSource.settings.host, dataSource.settings.port, dataSource.settings.options).database(dataSource.settings.database);
|
||||||
|
|
||||||
createdbif(
|
createdbif(
|
||||||
dataSource.client,
|
dataSource.client,
|
||||||
errorHandler(callback, function() {
|
errorHandler(callback, function () {
|
||||||
dataSource.connector = new CradleAdapter(dataSource.client);
|
dataSource.connector = new CradleAdapter(dataSource.client);
|
||||||
process.nextTick(callback);
|
process.nextTick(callback);
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
CradleAdapter.prototype.disconnect = function() {
|
CradleAdapter.prototype.disconnect = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write methods
|
* Write methods
|
||||||
*/
|
*/
|
||||||
CradleAdapter.prototype.define = function(descr) {
|
CradleAdapter.prototype.define = function (descr) {
|
||||||
this._models[descr.model.modelName] = descr;
|
this._models[descr.model.modelName] = descr;
|
||||||
};
|
};
|
||||||
|
|
||||||
CradleAdapter.prototype.create = function(model, data, callback) {
|
CradleAdapter.prototype.create = function (model, data, callback) {
|
||||||
this.client.save(
|
this.client.save(
|
||||||
stringify(data.id),
|
stringify(data.id),
|
||||||
naturalize(data, model),
|
naturalize(data, model),
|
||||||
errorHandler(callback, function(res, cb) {
|
errorHandler(callback, function (res, cb) {
|
||||||
cb(res.id);
|
cb(res.id);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
CradleAdapter.prototype.save = function(model, data, callback) {
|
CradleAdapter.prototype.save = function (model, data, callback) {
|
||||||
this.client.save(
|
this.client.save(
|
||||||
stringify(data.id),
|
stringify(data.id),
|
||||||
naturalize(data, model),
|
naturalize(data, model),
|
||||||
|
@ -206,21 +212,21 @@ CradleAdapter.prototype.save = function(model, data, callback) {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
CradleAdapter.prototype.updateAttributes = function(model, id, data, callback) {
|
CradleAdapter.prototype.updateAttributes = function (model, id, data, callback) {
|
||||||
this.client.merge(
|
this.client.merge(
|
||||||
stringify(id),
|
stringify(id),
|
||||||
data,
|
data,
|
||||||
errorHandler(callback, function(doc, cb) {
|
errorHandler(callback, function (doc, cb) {
|
||||||
cb(idealize(doc));
|
cb(idealize(doc));
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
CradleAdapter.prototype.updateOrCreate = function(model, data, callback) {
|
CradleAdapter.prototype.updateOrCreate = function (model, data, callback) {
|
||||||
this.client.get(
|
this.client.get(
|
||||||
stringify(data.id),
|
stringify(data.id),
|
||||||
function (err, doc) {
|
function (err, doc) {
|
||||||
if(err) {
|
if (err) {
|
||||||
this.create(model, data, callback);
|
this.create(model, data, callback);
|
||||||
} else {
|
} else {
|
||||||
this.updateAttributes(model, data.id, data, callback);
|
this.updateAttributes(model, data.id, data, callback);
|
||||||
|
@ -232,54 +238,55 @@ CradleAdapter.prototype.updateOrCreate = function(model, data, callback) {
|
||||||
/**
|
/**
|
||||||
* Read methods
|
* Read methods
|
||||||
*/
|
*/
|
||||||
CradleAdapter.prototype.exists = function(model, id, callback) {
|
CradleAdapter.prototype.exists = function (model, id, callback) {
|
||||||
this.client.get(
|
this.client.get(
|
||||||
stringify(id),
|
stringify(id),
|
||||||
errorHandler(callback, function(doc, cb) {
|
errorHandler(callback, function (doc, cb) {
|
||||||
cb(!!doc);
|
cb(!!doc);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
CradleAdapter.prototype.find = function(model, id, callback) {
|
CradleAdapter.prototype.find = function (model, id, callback) {
|
||||||
this.client.get(
|
this.client.get(
|
||||||
stringify(id),
|
stringify(id),
|
||||||
errorHandler(callback, function(doc, cb) {
|
errorHandler(callback, function (doc, cb) {
|
||||||
cb(idealize(doc));
|
cb(idealize(doc));
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
CradleAdapter.prototype.count = function(model, callback, where) {
|
CradleAdapter.prototype.count = function (model, callback, where) {
|
||||||
this.models(
|
this.models(
|
||||||
model,
|
model,
|
||||||
{where: where},
|
{where: where},
|
||||||
callback,
|
callback,
|
||||||
function(docs, cb) {
|
function (docs, cb) {
|
||||||
cb(docs.length);
|
cb(docs.length);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
CradleAdapter.prototype.models = function(model, filter, callback, func) {
|
CradleAdapter.prototype.models = function (model, filter, callback, func) {
|
||||||
var limit = 200;
|
var limit = 200;
|
||||||
var skip = 0;
|
var skip = 0;
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
limit = filter.limit || limit;
|
limit = filter.limit || limit;
|
||||||
skip = filter.skip ||skip;
|
skip = filter.skip || skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.client.save('_design/'+model, {
|
self.client.save('_design/' + model, {
|
||||||
views : {
|
views: {
|
||||||
all : {
|
all: {
|
||||||
map : 'function(doc) { if (doc.nature == "'+model+'") { emit(doc._id, doc); } }'
|
map: 'function(doc) { if (doc.nature == "' + model + '") { emit(doc._id, doc); } }'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, function() {
|
}, function () {
|
||||||
self.client.view(model+'/all', {include_docs:true, limit:limit, skip:skip}, errorHandler(callback, function(res, cb) {
|
self.client.view(model + '/all', {include_docs: true, limit: limit, skip: skip},
|
||||||
var docs = res.map(function(doc) {
|
errorHandler(callback, function (res, cb) {
|
||||||
|
var docs = res.map(function (doc) {
|
||||||
return idealize(doc);
|
return idealize(doc);
|
||||||
});
|
});
|
||||||
var filtered = filtering(docs, model, filter, this._models)
|
var filtered = filtering(docs, model, filter, this._models)
|
||||||
|
@ -289,7 +296,7 @@ CradleAdapter.prototype.models = function(model, filter, callback, func) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
CradleAdapter.prototype.all = function(model, filter, callback) {
|
CradleAdapter.prototype.all = function (model, filter, callback) {
|
||||||
this.models(
|
this.models(
|
||||||
model,
|
model,
|
||||||
filter,
|
filter,
|
||||||
|
@ -300,7 +307,7 @@ CradleAdapter.prototype.all = function(model, filter, callback) {
|
||||||
/**
|
/**
|
||||||
* Detroy methods
|
* Detroy methods
|
||||||
*/
|
*/
|
||||||
CradleAdapter.prototype.destroy = function(model, id, callback) {
|
CradleAdapter.prototype.destroy = function (model, id, callback) {
|
||||||
this.client.remove(
|
this.client.remove(
|
||||||
stringify(id),
|
stringify(id),
|
||||||
function (err, doc) {
|
function (err, doc) {
|
||||||
|
@ -309,23 +316,23 @@ CradleAdapter.prototype.destroy = function(model, id, callback) {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
CradleAdapter.prototype.destroyAll = function(model, callback) {
|
CradleAdapter.prototype.destroyAll = function (model, callback) {
|
||||||
this.models(
|
this.models(
|
||||||
model,
|
model,
|
||||||
null,
|
null,
|
||||||
callback,
|
callback,
|
||||||
function(docs, cb) {
|
function (docs, cb) {
|
||||||
var docIds = docs.map(function(doc) {
|
var docIds = docs.map(function (doc) {
|
||||||
return doc.id;
|
return doc.id;
|
||||||
});
|
});
|
||||||
this.client.get(docIds, function(err, res) {
|
this.client.get(docIds, function (err, res) {
|
||||||
if(err) cb(err);
|
if (err) cb(err);
|
||||||
|
|
||||||
var funcs = res.map(function(doc) {
|
var funcs = res.map(function (doc) {
|
||||||
return this.client.remove.bind(this.client);
|
return this.client.remove.bind(this.client);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
var args = res.map(function(doc) {
|
var args = res.map(function (doc) {
|
||||||
return [doc._id, doc._rev];
|
return [doc._id, doc._rev];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,20 +11,21 @@ function WebService() {
|
||||||
|
|
||||||
WebService.prototype.installPostProcessor = function installPostProcessor(descr) {
|
WebService.prototype.installPostProcessor = function installPostProcessor(descr) {
|
||||||
var dates = [];
|
var dates = [];
|
||||||
Object.keys(descr.properties).forEach(function(column) {
|
Object.keys(descr.properties).forEach(function (column) {
|
||||||
if (descr.properties[column].type.name === 'Date') {
|
if (descr.properties[column].type.name === 'Date') {
|
||||||
dates.push(column);
|
dates.push(column);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var postProcessor = function(model) {
|
var postProcessor = function (model) {
|
||||||
var max = dates.length;
|
var max = dates.length;
|
||||||
for (var i = 0; i < max; i++) {
|
for (var i = 0; i < max; i++) {
|
||||||
var column = dates[i];
|
var column = dates[i];
|
||||||
if (model[column]) {
|
if (model[column]) {
|
||||||
model[column] = new Date(model[column]);
|
model[column] = new Date(model[column]);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
descr.postProcessor = postProcessor;
|
descr.postProcessor = postProcessor;
|
||||||
|
@ -32,7 +33,7 @@ WebService.prototype.installPostProcessor = function installPostProcessor(descr)
|
||||||
|
|
||||||
WebService.prototype.preProcess = function preProcess(data) {
|
WebService.prototype.preProcess = function preProcess(data) {
|
||||||
var result = {};
|
var result = {};
|
||||||
Object.keys(data).forEach(function(key) {
|
Object.keys(data).forEach(function (key) {
|
||||||
if (data[key] != null) {
|
if (data[key] != null) {
|
||||||
result[key] = data[key];
|
result[key] = data[key];
|
||||||
}
|
}
|
||||||
|
@ -55,7 +56,8 @@ WebService.prototype.postProcessMultiple = function postProcessMultiple(model, d
|
||||||
if (data[i]) {
|
if (data[i]) {
|
||||||
postProcessor(data[i]);
|
postProcessor(data[i]);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ function Memory(m) {
|
||||||
|
|
||||||
util.inherits(Memory, Connector);
|
util.inherits(Memory, Connector);
|
||||||
|
|
||||||
Memory.prototype.connect = function(callback) {
|
Memory.prototype.connect = function (callback) {
|
||||||
if (this.isTransaction) {
|
if (this.isTransaction) {
|
||||||
this.onTransactionExec = callback;
|
this.onTransactionExec = callback;
|
||||||
} else {
|
} else {
|
||||||
|
@ -52,13 +52,13 @@ Memory.prototype.create = function create(model, data, callback) {
|
||||||
// FIXME: [rfeng] We need to generate unique ids based on the id type
|
// FIXME: [rfeng] We need to generate unique ids based on the id type
|
||||||
// FIXME: [rfeng] We don't support composite ids yet
|
// FIXME: [rfeng] We don't support composite ids yet
|
||||||
var currentId = this.ids[model];
|
var currentId = this.ids[model];
|
||||||
if(currentId === undefined) {
|
if (currentId === undefined) {
|
||||||
// First time
|
// First time
|
||||||
this.ids[model] = 1;
|
this.ids[model] = 1;
|
||||||
currentId = 1;
|
currentId = 1;
|
||||||
}
|
}
|
||||||
var id = this.getIdValue(model, data) || currentId;
|
var id = this.getIdValue(model, data) || currentId;
|
||||||
if(id > currentId) {
|
if (id > currentId) {
|
||||||
// If the id is passed in and the value is greater than the current id
|
// If the id is passed in and the value is greater than the current id
|
||||||
currentId = id;
|
currentId = id;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ Memory.prototype.create = function create(model, data, callback) {
|
||||||
id = (props[idName] && props[idName].type && props[idName].type(id)) || id;
|
id = (props[idName] && props[idName].type && props[idName].type(id)) || id;
|
||||||
this.setIdValue(model, data, id);
|
this.setIdValue(model, data, id);
|
||||||
this.cache[model][id] = JSON.stringify(data);
|
this.cache[model][id] = JSON.stringify(data);
|
||||||
process.nextTick(function() {
|
process.nextTick(function () {
|
||||||
callback(null, id);
|
callback(null, id);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -113,17 +113,17 @@ Memory.prototype.destroy = function destroy(model, id, callback) {
|
||||||
process.nextTick(callback);
|
process.nextTick(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Memory.prototype.fromDb = function(model, data) {
|
Memory.prototype.fromDb = function (model, data) {
|
||||||
if (!data) return null;
|
if (!data) return null;
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
var props = this._models[model].properties;
|
var props = this._models[model].properties;
|
||||||
for(var key in data) {
|
for (var key in data) {
|
||||||
var val = data[key];
|
var val = data[key];
|
||||||
if (val === undefined || val === null) {
|
if (val === undefined || val === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (props[key]) {
|
if (props[key]) {
|
||||||
switch(props[key].type.name) {
|
switch (props[key].type.name) {
|
||||||
case 'Date':
|
case 'Date':
|
||||||
val = new Date(val.toString().replace(/GMT.*$/, 'GMT'));
|
val = new Date(val.toString().replace(/GMT.*$/, 'GMT'));
|
||||||
break;
|
break;
|
||||||
|
@ -168,7 +168,7 @@ Memory.prototype.all = function all(model, filter, callback) {
|
||||||
var nearFilter = geo.nearFilter(filter.where);
|
var nearFilter = geo.nearFilter(filter.where);
|
||||||
|
|
||||||
// geo sorting
|
// geo sorting
|
||||||
if(nearFilter) {
|
if (nearFilter) {
|
||||||
nodes = geo.filter(nodes, nearFilter);
|
nodes = geo.filter(nodes, nearFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ Memory.prototype.all = function all(model, filter, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// field selection
|
// field selection
|
||||||
if(filter.fields) {
|
if (filter.fields) {
|
||||||
nodes = nodes.map(utils.selectFields(filter.fields));
|
nodes = nodes.map(utils.selectFields(filter.fields));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,11 +197,11 @@ Memory.prototype.all = function all(model, filter, callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
function sorting(a, b) {
|
function sorting(a, b) {
|
||||||
for (var i=0, l=this.length; i<l; i++) {
|
for (var i = 0, l = this.length; i < l; i++) {
|
||||||
if (a[this[i].key] > b[this[i].key]) {
|
if (a[this[i].key] > b[this[i].key]) {
|
||||||
return 1*this[i].reverse;
|
return 1 * this[i].reverse;
|
||||||
} else if (a[this[i].key] < b[this[i].key]) {
|
} else if (a[this[i].key] < b[this[i].key]) {
|
||||||
return -1*this[i].reverse;
|
return -1 * this[i].reverse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -231,7 +231,7 @@ function applyFilter(filter) {
|
||||||
if (typeof value === 'undefined') return undefined;
|
if (typeof value === '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;
|
||||||
|
@ -241,10 +241,10 @@ function applyFilter(filter) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isNum(example.gt) && example.gt < value) return true;
|
if (isNum(example.gt) && example.gt < value) return true;
|
||||||
if(isNum(example.gte) && example.gte <= value) return true;
|
if (isNum(example.gte) && example.gte <= value) return true;
|
||||||
if(isNum(example.lt) && example.lt > value) return true;
|
if (isNum(example.lt) && example.lt > value) return true;
|
||||||
if(isNum(example.lte) && example.lte >= value) return true;
|
if (isNum(example.lte) && example.lte >= value) return true;
|
||||||
}
|
}
|
||||||
// not strict equality
|
// not strict equality
|
||||||
return (example !== null ? example.toString() : example) == (value !== null ? value.toString() : value);
|
return (example !== null ? example.toString() : example) == (value !== null ? value.toString() : value);
|
||||||
|
@ -256,7 +256,7 @@ function applyFilter(filter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory.prototype.destroyAll = function destroyAll(model, where, callback) {
|
Memory.prototype.destroyAll = function destroyAll(model, where, callback) {
|
||||||
if(!callback && 'function' === typeof where) {
|
if (!callback && 'function' === typeof where) {
|
||||||
callback = where;
|
callback = where;
|
||||||
where = undefined;
|
where = undefined;
|
||||||
}
|
}
|
||||||
|
@ -266,11 +266,11 @@ Memory.prototype.destroyAll = function destroyAll(model, where, callback) {
|
||||||
filter = applyFilter({where: where});
|
filter = applyFilter({where: where});
|
||||||
}
|
}
|
||||||
Object.keys(cache).forEach(function (id) {
|
Object.keys(cache).forEach(function (id) {
|
||||||
if(!filter || filter(this.fromDb(model, cache[id]))) {
|
if (!filter || filter(this.fromDb(model, cache[id]))) {
|
||||||
delete cache[id];
|
delete cache[id];
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
if(!where) {
|
if (!where) {
|
||||||
this.cache[model] = {};
|
this.cache[model] = {};
|
||||||
}
|
}
|
||||||
process.nextTick(callback);
|
process.nextTick(callback);
|
||||||
|
@ -292,9 +292,9 @@ Memory.prototype.count = function count(model, callback, where) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Memory.prototype.updateAttributes = function updateAttributes(model, id, data, cb) {
|
Memory.prototype.updateAttributes = function updateAttributes(model, id, data, cb) {
|
||||||
if(!id) {
|
if (!id) {
|
||||||
var err = new Error('You must provide an id when updating attributes!');
|
var err = new Error('You must provide an id when updating attributes!');
|
||||||
if(cb) {
|
if (cb) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
} else {
|
} else {
|
||||||
throw err;
|
throw err;
|
||||||
|
@ -307,7 +307,7 @@ Memory.prototype.updateAttributes = function updateAttributes(model, id, data, c
|
||||||
var modelAsString = cachedModels && this.cache[model][id];
|
var modelAsString = cachedModels && this.cache[model][id];
|
||||||
var modelData = modelAsString && JSON.parse(modelAsString);
|
var modelData = modelAsString && JSON.parse(modelAsString);
|
||||||
|
|
||||||
if(modelData) {
|
if (modelData) {
|
||||||
this.save(model, merge(modelData, data), cb);
|
this.save(model, merge(modelData, data), cb);
|
||||||
} else {
|
} else {
|
||||||
cb(new Error('Could not update attributes. Object with id ' + id + ' does not exist!'));
|
cb(new Error('Could not update attributes. Object with id ' + id + ' does not exist!'));
|
||||||
|
@ -318,7 +318,7 @@ Memory.prototype.transaction = function () {
|
||||||
return new Memory(this);
|
return new Memory(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
Memory.prototype.exec = function(callback) {
|
Memory.prototype.exec = function (callback) {
|
||||||
this.onTransactionExec();
|
this.onTransactionExec();
|
||||||
setTimeout(callback, 50);
|
setTimeout(callback, 50);
|
||||||
};
|
};
|
||||||
|
|
|
@ -190,6 +190,7 @@ Neo4j.prototype.updateIndexes = function updateIndexes(model, node, cb) {
|
||||||
done();
|
done();
|
||||||
|
|
||||||
var error = false;
|
var error = false;
|
||||||
|
|
||||||
function done(err) {
|
function done(err) {
|
||||||
error = error || err;
|
error = error || err;
|
||||||
if (--wait === 0) {
|
if (--wait === 0) {
|
||||||
|
|
106
lib/dao.js
106
lib/dao.js
|
@ -19,7 +19,6 @@ var utils = require('./utils');
|
||||||
var fieldsToArray = utils.fieldsToArray;
|
var fieldsToArray = utils.fieldsToArray;
|
||||||
var removeUndefined = utils.removeUndefined;
|
var removeUndefined = utils.removeUndefined;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DAO class - base class for all persist objects
|
* DAO class - base class for all persist objects
|
||||||
* provides **common API** to access any database connector.
|
* provides **common API** to access any database connector.
|
||||||
|
@ -32,10 +31,10 @@ var removeUndefined = utils.removeUndefined;
|
||||||
* @param {Object} data - initial object data
|
* @param {Object} data - initial object data
|
||||||
*/
|
*/
|
||||||
function DataAccessObject() {
|
function DataAccessObject() {
|
||||||
if(DataAccessObject._mixins) {
|
if (DataAccessObject._mixins) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var args = arguments;
|
var args = arguments;
|
||||||
DataAccessObject._mixins.forEach(function(m) {
|
DataAccessObject._mixins.forEach(function (m) {
|
||||||
m.call(self, args);
|
m.call(self, args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -51,17 +50,17 @@ function getIdValue(m, data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setIdValue(m, data, value) {
|
function setIdValue(m, data, value) {
|
||||||
if(data) {
|
if (data) {
|
||||||
data[idName(m)] = value;
|
data[idName(m)] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DataAccessObject._forDB = function (data) {
|
DataAccessObject._forDB = function (data) {
|
||||||
if(!(this.getDataSource().isRelational && this.getDataSource().isRelational())) {
|
if (!(this.getDataSource().isRelational && this.getDataSource().isRelational())) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
var res = {};
|
var res = {};
|
||||||
for(var propName in data) {
|
for (var propName in data) {
|
||||||
var type = this.getPropertyType(propName);
|
var type = this.getPropertyType(propName);
|
||||||
if (type === 'JSON' || type === 'Any' || type === 'Object' || data[propName] instanceof Array) {
|
if (type === 'JSON' || type === 'Any' || type === 'Object' || data[propName] instanceof Array) {
|
||||||
res[propName] = JSON.stringify(data[propName]);
|
res[propName] = JSON.stringify(data[propName]);
|
||||||
|
@ -94,7 +93,8 @@ DataAccessObject.create = function (data, callback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof callback !== 'function') {
|
if (typeof callback !== 'function') {
|
||||||
callback = function () {};
|
callback = function () {
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
|
@ -110,8 +110,8 @@ DataAccessObject.create = function (data, callback) {
|
||||||
|
|
||||||
var instances = [];
|
var instances = [];
|
||||||
for (var i = 0; i < data.length; i += 1) {
|
for (var i = 0; i < data.length; i += 1) {
|
||||||
(function(d, i) {
|
(function (d, i) {
|
||||||
instances.push(Model.create(d, function(err, inst) {
|
instances.push(Model.create(d, function (err, inst) {
|
||||||
if (err) {
|
if (err) {
|
||||||
errors[i] = err;
|
errors[i] = err;
|
||||||
gotError = true;
|
gotError = true;
|
||||||
|
@ -130,7 +130,6 @@ DataAccessObject.create = function (data, callback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var obj;
|
var obj;
|
||||||
// if we come from save
|
// if we come from save
|
||||||
if (data instanceof Model && !getIdValue(this, data)) {
|
if (data instanceof Model && !getIdValue(this, data)) {
|
||||||
|
@ -141,7 +140,7 @@ DataAccessObject.create = function (data, callback) {
|
||||||
data = obj.toObject(true);
|
data = obj.toObject(true);
|
||||||
|
|
||||||
// validation required
|
// validation required
|
||||||
obj.isValid(function(valid) {
|
obj.isValid(function (valid) {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
create();
|
create();
|
||||||
} else {
|
} else {
|
||||||
|
@ -150,8 +149,8 @@ DataAccessObject.create = function (data, callback) {
|
||||||
}, data);
|
}, data);
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
obj.trigger('create', function(createDone) {
|
obj.trigger('create', function (createDone) {
|
||||||
obj.trigger('save', function(saveDone) {
|
obj.trigger('save', function (saveDone) {
|
||||||
|
|
||||||
var _idName = idName(Model);
|
var _idName = idName(Model);
|
||||||
this._adapter().create(modelName, this.constructor._forDB(obj.toObject(true)), function (err, id, rev) {
|
this._adapter().create(modelName, this.constructor._forDB(obj.toObject(true)), function (err, id, rev) {
|
||||||
|
@ -188,8 +187,8 @@ DataAccessObject.create = function (data, callback) {
|
||||||
*/
|
*/
|
||||||
function setRemoting(fn, options) {
|
function setRemoting(fn, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
for(var opt in options) {
|
for (var opt in options) {
|
||||||
if(options.hasOwnProperty(opt)) {
|
if (options.hasOwnProperty(opt)) {
|
||||||
fn[opt] = options[opt];
|
fn[opt] = options[opt];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +249,6 @@ setRemoting(DataAccessObject.upsert, {
|
||||||
http: {verb: 'put', path: '/'}
|
http: {verb: 'put', path: '/'}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find one record, same as `all`, limited by 1 and return object, not collection,
|
* Find one record, same as `all`, limited by 1 and return object, not collection,
|
||||||
* if not found, create using data provided as second argument
|
* if not found, create using data provided as second argument
|
||||||
|
@ -268,7 +266,8 @@ DataAccessObject.findOrCreate = function findOrCreate(query, data, callback) {
|
||||||
data = query && query.where;
|
data = query && query.where;
|
||||||
}
|
}
|
||||||
if (typeof callback === 'undefined') {
|
if (typeof callback === 'undefined') {
|
||||||
callback = function () {};
|
callback = function () {
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var t = this;
|
var t = this;
|
||||||
|
@ -383,22 +382,22 @@ DataAccessObject._coerce = function (where) {
|
||||||
return new OrigDate(arg);
|
return new OrigDate(arg);
|
||||||
};
|
};
|
||||||
} else if (DataType === Boolean) {
|
} else if (DataType === Boolean) {
|
||||||
DataType = function(val) {
|
DataType = function (val) {
|
||||||
if(val === 'true') {
|
if (val === 'true') {
|
||||||
return true;
|
return true;
|
||||||
} else if(val === 'false') {
|
} else if (val === 'false') {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return Boolean(val);
|
return Boolean(val);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else if(DataType === Number) {
|
} else if (DataType === Number) {
|
||||||
// This fixes a regression in mongodb connector
|
// This fixes a regression in mongodb connector
|
||||||
// For numbers, only convert it produces a valid number
|
// For numbers, only convert it produces a valid number
|
||||||
// LoopBack by default injects a number id. We should fix it based
|
// LoopBack by default injects a number id. We should fix it based
|
||||||
// on the connector's input, for example, MongoDB should use string
|
// on the connector's input, for example, MongoDB should use string
|
||||||
// while RDBs typically use number
|
// while RDBs typically use number
|
||||||
DataType = function(val) {
|
DataType = function (val) {
|
||||||
var num = Number(val);
|
var num = Number(val);
|
||||||
return !isNaN(num) ? num : val;
|
return !isNaN(num) ? num : val;
|
||||||
};
|
};
|
||||||
|
@ -418,7 +417,7 @@ DataAccessObject._coerce = function (where) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var val = where[p];
|
var val = where[p];
|
||||||
if(val === null || val === undefined) {
|
if (val === null || val === undefined) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Check there is an operator
|
// Check there is an operator
|
||||||
|
@ -485,7 +484,7 @@ DataAccessObject.find = function find(params, cb) {
|
||||||
|
|
||||||
params = params || {};
|
params = params || {};
|
||||||
|
|
||||||
if(params.where) {
|
if (params.where) {
|
||||||
params.where = this._coerce(params.where);
|
params.where = this._coerce(params.where);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,25 +493,25 @@ DataAccessObject.find = function find(params, cb) {
|
||||||
var supportsGeo = !!this.getDataSource().connector.buildNearFilter;
|
var supportsGeo = !!this.getDataSource().connector.buildNearFilter;
|
||||||
|
|
||||||
// normalize fields as array of included property names
|
// normalize fields as array of included property names
|
||||||
if(fields) {
|
if (fields) {
|
||||||
params.fields = fieldsToArray(fields, Object.keys(this.definition.properties));
|
params.fields = fieldsToArray(fields, Object.keys(this.definition.properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
params = removeUndefined(params);
|
params = removeUndefined(params);
|
||||||
if(near) {
|
if (near) {
|
||||||
if(supportsGeo) {
|
if (supportsGeo) {
|
||||||
// convert it
|
// convert it
|
||||||
this.getDataSource().connector.buildNearFilter(params, near);
|
this.getDataSource().connector.buildNearFilter(params, near);
|
||||||
} else if(params.where) {
|
} else if (params.where) {
|
||||||
// do in memory query
|
// do in memory query
|
||||||
// using all documents
|
// using all documents
|
||||||
this.getDataSource().connector.all(this.modelName, {}, function (err, data) {
|
this.getDataSource().connector.all(this.modelName, {}, function (err, data) {
|
||||||
var memory = new Memory();
|
var memory = new Memory();
|
||||||
var modelName = constr.modelName;
|
var modelName = constr.modelName;
|
||||||
|
|
||||||
if(err) {
|
if (err) {
|
||||||
cb(err);
|
cb(err);
|
||||||
} else if(Array.isArray(data)) {
|
} else if (Array.isArray(data)) {
|
||||||
memory.define({
|
memory.define({
|
||||||
properties: constr.dataSource.definitions[constr.modelName].properties,
|
properties: constr.dataSource.definitions[constr.modelName].properties,
|
||||||
settings: constr.dataSource.definitions[constr.modelName].settings,
|
settings: constr.dataSource.definitions[constr.modelName].settings,
|
||||||
|
@ -552,7 +551,7 @@ DataAccessObject.find = function find(params, cb) {
|
||||||
if (data && data.countBeforeLimit) {
|
if (data && data.countBeforeLimit) {
|
||||||
data.countBeforeLimit = data.countBeforeLimit;
|
data.countBeforeLimit = data.countBeforeLimit;
|
||||||
}
|
}
|
||||||
if(!supportsGeo && near) {
|
if (!supportsGeo && near) {
|
||||||
data = geo.filter(data, near);
|
data = geo.filter(data, near);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,22 +598,21 @@ setRemoting(DataAccessObject.findOne, {
|
||||||
http: {verb: 'get', path: '/findOne'}
|
http: {verb: 'get', path: '/findOne'}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy all matching records
|
* Destroy all matching records
|
||||||
* @param {Object} [where] An object that defines the criteria
|
* @param {Object} [where] An object that defines the criteria
|
||||||
* @param {Function} [cb] - callback called with (err)
|
* @param {Function} [cb] - callback called with (err)
|
||||||
*/
|
*/
|
||||||
DataAccessObject.remove =
|
DataAccessObject.remove =
|
||||||
DataAccessObject.deleteAll =
|
DataAccessObject.deleteAll =
|
||||||
DataAccessObject.destroyAll = function destroyAll(where, cb) {
|
DataAccessObject.destroyAll = function destroyAll(where, cb) {
|
||||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||||
|
|
||||||
if(!cb && 'function' === typeof where) {
|
if (!cb && 'function' === typeof where) {
|
||||||
cb = where;
|
cb = where;
|
||||||
where = undefined;
|
where = undefined;
|
||||||
}
|
}
|
||||||
if(!where) {
|
if (!where) {
|
||||||
this.getDataSource().connector.destroyAll(this.modelName, function (err, data) {
|
this.getDataSource().connector.destroyAll(this.modelName, function (err, data) {
|
||||||
cb && cb(err, data);
|
cb && cb(err, data);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
@ -626,7 +624,7 @@ DataAccessObject.destroyAll = function destroyAll(where, cb) {
|
||||||
cb && cb(err, data);
|
cb && cb(err, data);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a record by id
|
* Destroy a record by id
|
||||||
|
@ -634,7 +632,7 @@ DataAccessObject.destroyAll = function destroyAll(where, cb) {
|
||||||
* @param {Function} cb - callback called with (err)
|
* @param {Function} cb - callback called with (err)
|
||||||
*/
|
*/
|
||||||
DataAccessObject.removeById =
|
DataAccessObject.removeById =
|
||||||
DataAccessObject.deleteById =
|
DataAccessObject.deleteById =
|
||||||
DataAccessObject.destroyById = function deleteById(id, cb) {
|
DataAccessObject.destroyById = function deleteById(id, cb) {
|
||||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||||
|
|
||||||
|
@ -652,7 +650,6 @@ setRemoting(DataAccessObject.deleteById, {
|
||||||
http: {verb: 'del', path: '/:id'}
|
http: {verb: 'del', path: '/:id'}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return count of matched records
|
* Return count of matched records
|
||||||
*
|
*
|
||||||
|
@ -671,7 +668,6 @@ DataAccessObject.count = function (where, cb) {
|
||||||
this.getDataSource().connector.count(this.modelName, cb, where);
|
this.getDataSource().connector.count(this.modelName, cb, where);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// count ~ remoting attributes
|
// count ~ remoting attributes
|
||||||
setRemoting(DataAccessObject.count, {
|
setRemoting(DataAccessObject.count, {
|
||||||
description: 'Count instances of the model matched by where from the data source',
|
description: 'Count instances of the model matched by where from the data source',
|
||||||
|
@ -680,7 +676,6 @@ setRemoting(DataAccessObject.count, {
|
||||||
http: {verb: 'get', path: '/count'}
|
http: {verb: 'get', path: '/count'}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save instance. When instance haven't id, create method called instead.
|
* Save instance. When instance haven't id, create method called instead.
|
||||||
* Triggers: validate, save, update | create
|
* Triggers: validate, save, update | create
|
||||||
|
@ -695,7 +690,8 @@ DataAccessObject.prototype.save = function (options, callback) {
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
callback = callback || function () {};
|
callback = callback || function () {
|
||||||
|
};
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (!('validate' in options)) {
|
if (!('validate' in options)) {
|
||||||
|
@ -752,7 +748,6 @@ DataAccessObject.prototype.save = function (options, callback) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
DataAccessObject.prototype.isNewRecord = function () {
|
DataAccessObject.prototype.isNewRecord = function () {
|
||||||
return !getIdValue(this.constructor, this);
|
return !getIdValue(this.constructor, this);
|
||||||
};
|
};
|
||||||
|
@ -771,8 +766,8 @@ DataAccessObject.prototype._adapter = function () {
|
||||||
* @triggers `destroy` hook (async) before and after destroying object
|
* @triggers `destroy` hook (async) before and after destroying object
|
||||||
*/
|
*/
|
||||||
DataAccessObject.prototype.remove =
|
DataAccessObject.prototype.remove =
|
||||||
DataAccessObject.prototype.delete =
|
DataAccessObject.prototype.delete =
|
||||||
DataAccessObject.prototype.destroy = function (cb) {
|
DataAccessObject.prototype.destroy = function (cb) {
|
||||||
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
if (stillConnecting(this.getDataSource(), this, arguments)) return;
|
||||||
|
|
||||||
this.trigger('destroy', function (destroyed) {
|
this.trigger('destroy', function (destroyed) {
|
||||||
|
@ -782,12 +777,11 @@ DataAccessObject.prototype.destroy = function (cb) {
|
||||||
}
|
}
|
||||||
|
|
||||||
destroyed(function () {
|
destroyed(function () {
|
||||||
if(cb) cb();
|
if (cb) cb();
|
||||||
});
|
});
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update single attribute
|
* Update single attribute
|
||||||
|
@ -829,7 +823,7 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, cb
|
||||||
}
|
}
|
||||||
|
|
||||||
// update instance's properties
|
// update instance's properties
|
||||||
for(var key in data) {
|
for (var key in data) {
|
||||||
inst[key] = data[key];
|
inst[key] = data[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,16 +836,17 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, cb
|
||||||
inst.trigger('save', function (saveDone) {
|
inst.trigger('save', function (saveDone) {
|
||||||
inst.trigger('update', function (done) {
|
inst.trigger('update', function (done) {
|
||||||
|
|
||||||
for(var key in data) {
|
for (var key in data) {
|
||||||
inst[key] = data[key];
|
inst[key] = data[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
inst._adapter().updateAttributes(model, getIdValue(inst.constructor, inst), inst.constructor._forDB(data), function (err) {
|
inst._adapter().updateAttributes(model, getIdValue(inst.constructor, inst), inst.constructor._forDB(data), function (err) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
// update $was attrs
|
// update $was attrs
|
||||||
for(var key in data) {
|
for (var key in data) {
|
||||||
inst.__dataWas[key] = inst.__data[key];
|
inst.__dataWas[key] = inst.__data[key];
|
||||||
};
|
}
|
||||||
|
;
|
||||||
}
|
}
|
||||||
done.call(inst, function () {
|
done.call(inst, function () {
|
||||||
saveDone.call(inst, function () {
|
saveDone.call(inst, function () {
|
||||||
|
@ -873,7 +868,6 @@ setRemoting(DataAccessObject.prototype.updateAttributes, {
|
||||||
http: {verb: 'put', path: '/'}
|
http: {verb: 'put', path: '/'}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload object from persistence
|
* Reload object from persistence
|
||||||
*
|
*
|
||||||
|
@ -887,11 +881,11 @@ DataAccessObject.prototype.reload = function reload(callback) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
setRemoting(DataAccessObject.prototype.reload, {
|
setRemoting(DataAccessObject.prototype.reload, {
|
||||||
description: 'Reload a model instance from the data source',
|
description: 'Reload a model instance from the data source',
|
||||||
returns: {arg: 'data', type: 'object', root: true}
|
returns: {arg: 'data', type: 'object', root: true}
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define readonly property on object
|
* Define readonly property on object
|
||||||
|
|
|
@ -15,8 +15,6 @@ var fs = require('fs');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
|
||||||
var existsSync = fs.existsSync || path.existsSync;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export public API
|
* Export public API
|
||||||
*/
|
*/
|
||||||
|
@ -65,12 +63,12 @@ function DataSource(name, settings, modelBuilder) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the first argument is a URL
|
// Check if the first argument is a URL
|
||||||
if(typeof name === 'string' && name.indexOf('://') !== -1 ) {
|
if (typeof name === 'string' && name.indexOf('://') !== -1) {
|
||||||
name = utils.parseSettings(name);
|
name = utils.parseSettings(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the settings is in the form of URL string
|
// Check if the settings is in the form of URL string
|
||||||
if(typeof settings === 'string' && settings.indexOf('://') !== -1 ) {
|
if (typeof settings === 'string' && settings.indexOf('://') !== -1) {
|
||||||
settings = utils.parseSettings(settings);
|
settings = utils.parseSettings(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,14 +89,15 @@ function DataSource(name, settings, modelBuilder) {
|
||||||
|
|
||||||
// DataAccessObject - connector defined or supply the default
|
// DataAccessObject - connector defined or supply the default
|
||||||
var dao = (connector && connector.DataAccessObject) || this.constructor.DataAccessObject;
|
var dao = (connector && connector.DataAccessObject) || this.constructor.DataAccessObject;
|
||||||
this.DataAccessObject = function() {};
|
this.DataAccessObject = function () {
|
||||||
|
};
|
||||||
|
|
||||||
// define DataAccessObject methods
|
// define DataAccessObject methods
|
||||||
Object.keys(dao).forEach(function (name) {
|
Object.keys(dao).forEach(function (name) {
|
||||||
var fn = dao[name];
|
var fn = dao[name];
|
||||||
this.DataAccessObject[name] = fn;
|
this.DataAccessObject[name] = fn;
|
||||||
|
|
||||||
if(typeof fn === 'function') {
|
if (typeof fn === 'function') {
|
||||||
this.defineOperation(name, {
|
this.defineOperation(name, {
|
||||||
accepts: fn.accepts,
|
accepts: fn.accepts,
|
||||||
'returns': fn.returns,
|
'returns': fn.returns,
|
||||||
|
@ -114,7 +113,7 @@ function DataSource(name, settings, modelBuilder) {
|
||||||
Object.keys(dao.prototype).forEach(function (name) {
|
Object.keys(dao.prototype).forEach(function (name) {
|
||||||
var fn = dao.prototype[name];
|
var fn = dao.prototype[name];
|
||||||
this.DataAccessObject.prototype[name] = fn;
|
this.DataAccessObject.prototype[name] = fn;
|
||||||
if(typeof fn === 'function') {
|
if (typeof fn === 'function') {
|
||||||
this.defineOperation(name, {
|
this.defineOperation(name, {
|
||||||
prototype: true,
|
prototype: true,
|
||||||
accepts: fn.accepts,
|
accepts: fn.accepts,
|
||||||
|
@ -129,15 +128,11 @@ function DataSource(name, settings, modelBuilder) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
util.inherits(DataSource, EventEmitter);
|
util.inherits(DataSource, EventEmitter);
|
||||||
|
|
||||||
// allow child classes to supply a data access object
|
// allow child classes to supply a data access object
|
||||||
DataSource.DataAccessObject = DataAccessObject;
|
DataSource.DataAccessObject = DataAccessObject;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the connector instance for backward compatibility with JugglingDB schema/adapter
|
* Set up the connector instance for backward compatibility with JugglingDB schema/adapter
|
||||||
* @private
|
* @private
|
||||||
|
@ -181,7 +176,7 @@ function connectorModuleNames(name) {
|
||||||
function tryModules(names, loader) {
|
function tryModules(names, loader) {
|
||||||
var mod;
|
var mod;
|
||||||
loader = loader || require;
|
loader = loader || require;
|
||||||
for(var m =0; m<names.length; m++) {
|
for (var m = 0; m < names.length; m++) {
|
||||||
try {
|
try {
|
||||||
mod = loader(names[m]);
|
mod = loader(names[m]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -200,11 +195,11 @@ function tryModules(names, loader) {
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
DataSource._resolveConnector = function(name, loader) {
|
DataSource._resolveConnector = function (name, loader) {
|
||||||
var names = connectorModuleNames(name);
|
var names = connectorModuleNames(name);
|
||||||
var connector = tryModules(names , loader);
|
var connector = tryModules(names, loader);
|
||||||
var error = null;
|
var error = null;
|
||||||
if(!connector) {
|
if (!connector) {
|
||||||
error = '\nWARNING: LoopBack connector "' + name
|
error = '\nWARNING: LoopBack connector "' + name
|
||||||
+ '" is not installed at any of the locations ' + names
|
+ '" is not installed at any of the locations ' + names
|
||||||
+ '. To fix, run:\n\n npm install '
|
+ '. To fix, run:\n\n npm install '
|
||||||
|
@ -223,22 +218,22 @@ DataSource._resolveConnector = function(name, loader) {
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.setup = function(name, settings) {
|
DataSource.prototype.setup = function (name, settings) {
|
||||||
var dataSource = this;
|
var dataSource = this;
|
||||||
var connector;
|
var connector;
|
||||||
|
|
||||||
// support single settings object
|
// support single settings object
|
||||||
if(name && typeof name === 'object' && !settings) {
|
if (name && typeof name === 'object' && !settings) {
|
||||||
settings = name;
|
settings = name;
|
||||||
name = undefined;
|
name = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(typeof settings === 'object') {
|
if (typeof settings === 'object') {
|
||||||
if(settings.initialize) {
|
if (settings.initialize) {
|
||||||
connector = settings;
|
connector = settings;
|
||||||
} else if(settings.connector) {
|
} else if (settings.connector) {
|
||||||
connector = settings.connector;
|
connector = settings.connector;
|
||||||
} else if(settings.adapter) {
|
} else if (settings.adapter) {
|
||||||
connector = settings.adapter;
|
connector = settings.adapter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,7 +244,7 @@ DataSource.prototype.setup = function(name, settings) {
|
||||||
// Check the debug env settings
|
// Check the debug env settings
|
||||||
var debugEnv = process.env.DEBUG || process.env.NODE_DEBUG || '';
|
var debugEnv = process.env.DEBUG || process.env.NODE_DEBUG || '';
|
||||||
var debugModules = debugEnv.split(/[\s,]+/);
|
var debugModules = debugEnv.split(/[\s,]+/);
|
||||||
if(debugModules.indexOf('loopback') !== -1) {
|
if (debugModules.indexOf('loopback') !== -1) {
|
||||||
this.settings.debug = true;
|
this.settings.debug = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +252,7 @@ DataSource.prototype.setup = function(name, settings) {
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
this.connecting = false;
|
this.connecting = false;
|
||||||
|
|
||||||
if(typeof connector === 'string') {
|
if (typeof connector === 'string') {
|
||||||
name = connector;
|
name = connector;
|
||||||
connector = undefined;
|
connector = undefined;
|
||||||
}
|
}
|
||||||
|
@ -273,7 +268,7 @@ DataSource.prototype.setup = function(name, settings) {
|
||||||
// The connector has not been resolved
|
// The connector has not been resolved
|
||||||
var result = DataSource._resolveConnector(name);
|
var result = DataSource._resolveConnector(name);
|
||||||
connector = result.connector;
|
connector = result.connector;
|
||||||
if(!connector) {
|
if (!connector) {
|
||||||
console.error(result.error);
|
console.error(result.error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -289,7 +284,7 @@ DataSource.prototype.setup = function(name, settings) {
|
||||||
throw new Error('Connector is not defined correctly: it should create `connector` member of dataSource');
|
throw new Error('Connector is not defined correctly: it should create `connector` member of dataSource');
|
||||||
}
|
}
|
||||||
this.connected = !err; // Connected now
|
this.connected = !err; // Connected now
|
||||||
if(this.connected) {
|
if (this.connected) {
|
||||||
this.emit('connected');
|
this.emit('connected');
|
||||||
} else {
|
} else {
|
||||||
// The connection fails, let's report it and hope it will be recovered in the next call
|
// The connection fails, let's report it and hope it will be recovered in the next call
|
||||||
|
@ -302,24 +297,24 @@ DataSource.prototype.setup = function(name, settings) {
|
||||||
if ('function' === typeof connector.initialize) {
|
if ('function' === typeof connector.initialize) {
|
||||||
// Call the async initialize method
|
// Call the async initialize method
|
||||||
connector.initialize(this, postInit);
|
connector.initialize(this, postInit);
|
||||||
} else if('function' === typeof connector) {
|
} else if ('function' === typeof connector) {
|
||||||
// Use the connector constructor directly
|
// Use the connector constructor directly
|
||||||
this.connector = new connector(this.settings);
|
this.connector = new connector(this.settings);
|
||||||
postInit();
|
postInit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dataSource.connect = function(cb) {
|
dataSource.connect = function (cb) {
|
||||||
var dataSource = this;
|
var dataSource = this;
|
||||||
if(dataSource.connected || dataSource.connecting) {
|
if (dataSource.connected || dataSource.connecting) {
|
||||||
process.nextTick(function() {
|
process.nextTick(function () {
|
||||||
cb && cb();
|
cb && cb();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dataSource.connecting = true;
|
dataSource.connecting = true;
|
||||||
if (dataSource.connector.connect) {
|
if (dataSource.connector.connect) {
|
||||||
dataSource.connector.connect(function(err, result) {
|
dataSource.connector.connect(function (err, result) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
dataSource.connected = true;
|
dataSource.connected = true;
|
||||||
dataSource.connecting = false;
|
dataSource.connecting = false;
|
||||||
|
@ -332,7 +327,7 @@ DataSource.prototype.setup = function(name, settings) {
|
||||||
cb && cb(err, result);
|
cb && cb(err, result);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
process.nextTick(function() {
|
process.nextTick(function () {
|
||||||
dataSource.connected = true;
|
dataSource.connected = true;
|
||||||
dataSource.connecting = false;
|
dataSource.connecting = false;
|
||||||
dataSource.emit('connected');
|
dataSource.emit('connected');
|
||||||
|
@ -343,7 +338,7 @@ DataSource.prototype.setup = function(name, settings) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function isModelClass(cls) {
|
function isModelClass(cls) {
|
||||||
if(!cls) {
|
if (!cls) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return cls.prototype instanceof ModelBaseClass;
|
return cls.prototype instanceof ModelBaseClass;
|
||||||
|
@ -351,7 +346,6 @@ function isModelClass(cls) {
|
||||||
|
|
||||||
DataSource.relationTypes = ['belongsTo', 'hasMany', 'hasAndBelongsToMany'];
|
DataSource.relationTypes = ['belongsTo', 'hasMany', 'hasAndBelongsToMany'];
|
||||||
|
|
||||||
|
|
||||||
function isModelDataSourceAttached(model) {
|
function isModelDataSourceAttached(model) {
|
||||||
return model && (!model.settings.unresolved) && (model.dataSource instanceof DataSource);
|
return model && (!model.settings.unresolved) && (model.dataSource instanceof DataSource);
|
||||||
}
|
}
|
||||||
|
@ -360,7 +354,7 @@ function isModelDataSourceAttached(model) {
|
||||||
* @param modelClass
|
* @param modelClass
|
||||||
* @param relations
|
* @param relations
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.defineRelations = function(modelClass, relations) {
|
DataSource.prototype.defineRelations = function (modelClass, relations) {
|
||||||
|
|
||||||
// Create a function for the closure in the loop
|
// Create a function for the closure in the loop
|
||||||
var createListener = function (name, relation, targetModel, throughModel) {
|
var createListener = function (name, relation, targetModel, throughModel) {
|
||||||
|
@ -501,12 +495,12 @@ DataSource.prototype.createModel = DataSource.prototype.define = function define
|
||||||
properties = properties || {};
|
properties = properties || {};
|
||||||
settings = settings || {};
|
settings = settings || {};
|
||||||
|
|
||||||
if(this.isRelational()) {
|
if (this.isRelational()) {
|
||||||
// Set the strict mode to be true for relational DBs by default
|
// Set the strict mode to be true for relational DBs by default
|
||||||
if(settings.strict === undefined || settings.strict === null) {
|
if (settings.strict === undefined || settings.strict === null) {
|
||||||
settings.strict = true;
|
settings.strict = true;
|
||||||
}
|
}
|
||||||
if(settings.strict === false) {
|
if (settings.strict === false) {
|
||||||
settings.strict = 'throw';
|
settings.strict = 'throw';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -514,7 +508,7 @@ DataSource.prototype.createModel = DataSource.prototype.define = function define
|
||||||
var modelClass = this.modelBuilder.define(className, properties, settings);
|
var modelClass = this.modelBuilder.define(className, properties, settings);
|
||||||
modelClass.dataSource = this;
|
modelClass.dataSource = this;
|
||||||
|
|
||||||
if(settings.unresolved) {
|
if (settings.unresolved) {
|
||||||
return modelClass;
|
return modelClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,7 +518,6 @@ DataSource.prototype.createModel = DataSource.prototype.define = function define
|
||||||
return modelClass;
|
return modelClass;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mixin DataAccessObject methods.
|
* Mixin DataAccessObject methods.
|
||||||
*
|
*
|
||||||
|
@ -536,14 +529,14 @@ DataSource.prototype.mixin = function (ModelCtor) {
|
||||||
var DAO = this.DataAccessObject;
|
var DAO = this.DataAccessObject;
|
||||||
|
|
||||||
// mixin DAO
|
// mixin DAO
|
||||||
jutil.mixin(ModelCtor, DAO, {proxyFunctions : true});
|
jutil.mixin(ModelCtor, DAO, {proxyFunctions: true});
|
||||||
|
|
||||||
// decorate operations as alias functions
|
// decorate operations as alias functions
|
||||||
Object.keys(ops).forEach(function (name) {
|
Object.keys(ops).forEach(function (name) {
|
||||||
var op = ops[name];
|
var op = ops[name];
|
||||||
var scope;
|
var scope;
|
||||||
|
|
||||||
if(op.enabled) {
|
if (op.enabled) {
|
||||||
scope = op.prototype ? ModelCtor.prototype : ModelCtor;
|
scope = op.prototype ? ModelCtor.prototype : ModelCtor;
|
||||||
// var sfn = scope[name] = function () {
|
// var sfn = scope[name] = function () {
|
||||||
// op.scope[op.fnName].apply(self, arguments);
|
// op.scope[op.fnName].apply(self, arguments);
|
||||||
|
@ -551,14 +544,14 @@ DataSource.prototype.mixin = function (ModelCtor) {
|
||||||
Object.keys(op)
|
Object.keys(op)
|
||||||
.filter(function (key) {
|
.filter(function (key) {
|
||||||
// filter out the following keys
|
// filter out the following keys
|
||||||
return ~ [
|
return ~[
|
||||||
'scope',
|
'scope',
|
||||||
'fnName',
|
'fnName',
|
||||||
'prototype'
|
'prototype'
|
||||||
].indexOf(key);
|
].indexOf(key);
|
||||||
})
|
})
|
||||||
.forEach(function (key) {
|
.forEach(function (key) {
|
||||||
if(typeof op[key] !== 'undefined') {
|
if (typeof op[key] !== 'undefined') {
|
||||||
op.scope[op.fnName][key] = op[key];
|
op.scope[op.fnName][key] = op[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -566,11 +559,11 @@ DataSource.prototype.mixin = function (ModelCtor) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
DataSource.prototype.getModel = function(name, forceCreate) {
|
DataSource.prototype.getModel = function (name, forceCreate) {
|
||||||
return this.modelBuilder.getModel(name, forceCreate);
|
return this.modelBuilder.getModel(name, forceCreate);
|
||||||
};
|
};
|
||||||
|
|
||||||
DataSource.prototype.getModelDefinition = function(name) {
|
DataSource.prototype.getModelDefinition = function (name) {
|
||||||
return this.modelBuilder.getModelDefinition(name);
|
return this.modelBuilder.getModelDefinition(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -581,12 +574,12 @@ DataSource.prototype.getModelDefinition = function(name) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DataSource.prototype.attach = function (modelClass) {
|
DataSource.prototype.attach = function (modelClass) {
|
||||||
if(modelClass.dataSource === this) {
|
if (modelClass.dataSource === this) {
|
||||||
// Already attached to the data source
|
// Already attached to the data source
|
||||||
return modelClass;
|
return modelClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(modelClass.modelBuilder !== this.modelBuilder) {
|
if (modelClass.modelBuilder !== this.modelBuilder) {
|
||||||
this.modelBuilder.definitions[modelClass.modelName] = modelClass.definition;
|
this.modelBuilder.definitions[modelClass.modelName] = modelClass.definition;
|
||||||
this.modelBuilder.models[modelClass.modelName] = modelClass;
|
this.modelBuilder.models[modelClass.modelName] = modelClass;
|
||||||
// reset the modelBuilder
|
// reset the modelBuilder
|
||||||
|
@ -684,7 +677,6 @@ DataSource.prototype.discoverModelDefinitions = function (options, cb) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The synchronous version of discoverModelDefinitions
|
* The synchronous version of discoverModelDefinitions
|
||||||
* @param {Object} options The options
|
* @param {Object} options The options
|
||||||
|
@ -765,7 +757,7 @@ DataSource.prototype.discoverModelPropertiesSync = function (modelName, options)
|
||||||
* @param {Object} options The options
|
* @param {Object} options The options
|
||||||
* @param {Function} [cb] The callback function
|
* @param {Function} [cb] The callback function
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.discoverPrimaryKeys= function(modelName, options, cb) {
|
DataSource.prototype.discoverPrimaryKeys = function (modelName, options, cb) {
|
||||||
this.freeze();
|
this.freeze();
|
||||||
if (this.connector.discoverPrimaryKeys) {
|
if (this.connector.discoverPrimaryKeys) {
|
||||||
this.connector.discoverPrimaryKeys(modelName, options, cb);
|
this.connector.discoverPrimaryKeys(modelName, options, cb);
|
||||||
|
@ -780,7 +772,7 @@ DataSource.prototype.discoverPrimaryKeys= function(modelName, options, cb) {
|
||||||
* @param {Object} options The options
|
* @param {Object} options The options
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.discoverPrimaryKeysSync= function(modelName, options) {
|
DataSource.prototype.discoverPrimaryKeysSync = function (modelName, options) {
|
||||||
this.freeze();
|
this.freeze();
|
||||||
if (this.connector.discoverPrimaryKeysSync) {
|
if (this.connector.discoverPrimaryKeysSync) {
|
||||||
return this.connector.discoverPrimaryKeysSync(modelName, options);
|
return this.connector.discoverPrimaryKeysSync(modelName, options);
|
||||||
|
@ -812,7 +804,7 @@ DataSource.prototype.discoverPrimaryKeysSync= function(modelName, options) {
|
||||||
* @param {Function} [cb] The callback function
|
* @param {Function} [cb] The callback function
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.discoverForeignKeys= function(modelName, options, cb) {
|
DataSource.prototype.discoverForeignKeys = function (modelName, options, cb) {
|
||||||
this.freeze();
|
this.freeze();
|
||||||
if (this.connector.discoverForeignKeys) {
|
if (this.connector.discoverForeignKeys) {
|
||||||
this.connector.discoverForeignKeys(modelName, options, cb);
|
this.connector.discoverForeignKeys(modelName, options, cb);
|
||||||
|
@ -828,7 +820,7 @@ DataSource.prototype.discoverForeignKeys= function(modelName, options, cb) {
|
||||||
* @param {Object} options The options
|
* @param {Object} options The options
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.discoverForeignKeysSync= function(modelName, options) {
|
DataSource.prototype.discoverForeignKeysSync = function (modelName, options) {
|
||||||
this.freeze();
|
this.freeze();
|
||||||
if (this.connector.discoverForeignKeysSync) {
|
if (this.connector.discoverForeignKeysSync) {
|
||||||
return this.connector.discoverForeignKeysSync(modelName, options);
|
return this.connector.discoverForeignKeysSync(modelName, options);
|
||||||
|
@ -860,7 +852,7 @@ DataSource.prototype.discoverForeignKeysSync= function(modelName, options) {
|
||||||
* @param {Object} options The options
|
* @param {Object} options The options
|
||||||
* @param {Function} [cb] The callback function
|
* @param {Function} [cb] The callback function
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.discoverExportedForeignKeys= function(modelName, options, cb) {
|
DataSource.prototype.discoverExportedForeignKeys = function (modelName, options, cb) {
|
||||||
this.freeze();
|
this.freeze();
|
||||||
if (this.connector.discoverExportedForeignKeys) {
|
if (this.connector.discoverExportedForeignKeys) {
|
||||||
this.connector.discoverExportedForeignKeys(modelName, options, cb);
|
this.connector.discoverExportedForeignKeys(modelName, options, cb);
|
||||||
|
@ -875,13 +867,13 @@ DataSource.prototype.discoverExportedForeignKeys= function(modelName, options, c
|
||||||
* @param {Object} options The options
|
* @param {Object} options The options
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.discoverExportedForeignKeysSync= function(modelName, options) {
|
DataSource.prototype.discoverExportedForeignKeysSync = function (modelName, options) {
|
||||||
this.freeze();
|
this.freeze();
|
||||||
if (this.connector.discoverExportedForeignKeysSync) {
|
if (this.connector.discoverExportedForeignKeysSync) {
|
||||||
return this.connector.discoverExportedForeignKeysSync(modelName, options);
|
return this.connector.discoverExportedForeignKeysSync(modelName, options);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
};
|
||||||
|
|
||||||
function capitalize(str) {
|
function capitalize(str) {
|
||||||
if (!str) {
|
if (!str) {
|
||||||
|
@ -913,19 +905,19 @@ function fromDBName(dbName, camelCase) {
|
||||||
DataSource.prototype.discoverSchema = function (modelName, options, cb) {
|
DataSource.prototype.discoverSchema = function (modelName, options, cb) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if(!cb && 'function' === typeof options) {
|
if (!cb && 'function' === typeof options) {
|
||||||
cb = options;
|
cb = options;
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
options.visited = {};
|
options.visited = {};
|
||||||
options.relations = false;
|
options.relations = false;
|
||||||
|
|
||||||
this.discoverSchemas(modelName, options, function(err, schemas) {
|
this.discoverSchemas(modelName, options, function (err, schemas) {
|
||||||
if(err) {
|
if (err) {
|
||||||
cb && cb(err, schemas);
|
cb && cb(err, schemas);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for(var s in schemas) {
|
for (var s in schemas) {
|
||||||
cb && cb(null, schemas[s]);
|
cb && cb(null, schemas[s]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -949,7 +941,7 @@ DataSource.prototype.discoverSchema = function (modelName, options, cb) {
|
||||||
DataSource.prototype.discoverSchemas = function (modelName, options, cb) {
|
DataSource.prototype.discoverSchemas = function (modelName, options, cb) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if(!cb && 'function' === typeof options) {
|
if (!cb && 'function' === typeof options) {
|
||||||
cb = options;
|
cb = options;
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
@ -1033,7 +1025,7 @@ DataSource.prototype.discoverSchemas = function (modelName, options, cb) {
|
||||||
options.visited = options.visited || {};
|
options.visited = options.visited || {};
|
||||||
var schemaKey = columns[0].owner + '.' + modelName;
|
var schemaKey = columns[0].owner + '.' + modelName;
|
||||||
if (!options.visited.hasOwnProperty(schemaKey)) {
|
if (!options.visited.hasOwnProperty(schemaKey)) {
|
||||||
if(self.settings.debug) {
|
if (self.settings.debug) {
|
||||||
console.log('Adding schema for ' + schemaKey);
|
console.log('Adding schema for ' + schemaKey);
|
||||||
}
|
}
|
||||||
options.visited[schemaKey] = schema;
|
options.visited[schemaKey] = schema;
|
||||||
|
@ -1083,11 +1075,11 @@ DataSource.prototype.discoverSchemas = function (modelName, options, cb) {
|
||||||
} else {
|
} else {
|
||||||
var moreTasks = [];
|
var moreTasks = [];
|
||||||
for (var t in otherTables) {
|
for (var t in otherTables) {
|
||||||
if(self.settings.debug) {
|
if (self.settings.debug) {
|
||||||
console.log('Discovering related schema for ' + schemaKey);
|
console.log('Discovering related schema for ' + schemaKey);
|
||||||
}
|
}
|
||||||
var newOptions = {};
|
var newOptions = {};
|
||||||
for(var key in options) {
|
for (var key in options) {
|
||||||
newOptions[key] = options[key];
|
newOptions[key] = options[key];
|
||||||
}
|
}
|
||||||
newOptions.owner = otherTables[t].owner;
|
newOptions.owner = otherTables[t].owner;
|
||||||
|
@ -1102,7 +1094,6 @@ DataSource.prototype.discoverSchemas = function (modelName, options, cb) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Discover schema from a given table/view synchronously
|
* Discover schema from a given table/view synchronously
|
||||||
*
|
*
|
||||||
|
@ -1234,7 +1225,7 @@ DataSource.prototype.discoverSchemasSync = function (modelName, options) {
|
||||||
console.log('Discovering related schema for ' + schemaKey);
|
console.log('Discovering related schema for ' + schemaKey);
|
||||||
}
|
}
|
||||||
var newOptions = {};
|
var newOptions = {};
|
||||||
for(var key in options) {
|
for (var key in options) {
|
||||||
newOptions[key] = options[key];
|
newOptions[key] = options[key];
|
||||||
}
|
}
|
||||||
newOptions.owner = otherTables[t].owner;
|
newOptions.owner = otherTables[t].owner;
|
||||||
|
@ -1275,7 +1266,7 @@ DataSource.prototype.discoverAndBuildModels = function (modelName, options, cb)
|
||||||
|
|
||||||
var models = self.modelBuilder.buildModels(schemaList);
|
var models = self.modelBuilder.buildModels(schemaList);
|
||||||
// Now attach the models to the data source
|
// Now attach the models to the data source
|
||||||
for(var m in models) {
|
for (var m in models) {
|
||||||
models[m].attachTo(self);
|
models[m].attachTo(self);
|
||||||
}
|
}
|
||||||
cb && cb(err, models);
|
cb && cb(err, models);
|
||||||
|
@ -1323,7 +1314,7 @@ DataSource.prototype.isActual = function (models, cb) {
|
||||||
models = undefined;
|
models = undefined;
|
||||||
}
|
}
|
||||||
if (cb) {
|
if (cb) {
|
||||||
process.nextTick(function() {
|
process.nextTick(function () {
|
||||||
cb(null, true);
|
cb(null, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1394,7 +1385,7 @@ DataSource.prototype.columnNames = function (modelName) {
|
||||||
* @param {String} modelName The model name
|
* @param {String} modelName The model name
|
||||||
* @returns {String} columnName for ID
|
* @returns {String} columnName for ID
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.idColumnName = function(modelName) {
|
DataSource.prototype.idColumnName = function (modelName) {
|
||||||
return this.getModelDefinition(modelName).idColumnName(this.connector.name);
|
return this.getModelDefinition(modelName).idColumnName(this.connector.name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1403,8 +1394,8 @@ DataSource.prototype.idColumnName = function(modelName) {
|
||||||
* @param {String} modelName The model name
|
* @param {String} modelName The model name
|
||||||
* @returns {String} property name for ID
|
* @returns {String} property name for ID
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.idName = function(modelName) {
|
DataSource.prototype.idName = function (modelName) {
|
||||||
if(!this.getModelDefinition(modelName).idName) {
|
if (!this.getModelDefinition(modelName).idName) {
|
||||||
console.error('No id name', this.getModelDefinition(modelName));
|
console.error('No id name', this.getModelDefinition(modelName));
|
||||||
}
|
}
|
||||||
return this.getModelDefinition(modelName).idName();
|
return this.getModelDefinition(modelName).idName();
|
||||||
|
@ -1419,7 +1410,6 @@ DataSource.prototype.idNames = function (modelName) {
|
||||||
return this.getModelDefinition(modelName).idNames();
|
return this.getModelDefinition(modelName).idNames();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define foreign key to another model
|
* Define foreign key to another model
|
||||||
* @param {String} className The model name that owns the key
|
* @param {String} className The model name that owns the key
|
||||||
|
@ -1431,10 +1421,10 @@ DataSource.prototype.defineForeignKey = function defineForeignKey(className, key
|
||||||
if (this.getModelDefinition(className).rawProperties[key]) return;
|
if (this.getModelDefinition(className).rawProperties[key]) return;
|
||||||
|
|
||||||
var defaultType = Number;
|
var defaultType = Number;
|
||||||
if(foreignClassName) {
|
if (foreignClassName) {
|
||||||
var foreignModel = this.getModelDefinition(foreignClassName);
|
var foreignModel = this.getModelDefinition(foreignClassName);
|
||||||
var pkName = foreignModel && foreignModel.idName();
|
var pkName = foreignModel && foreignModel.idName();
|
||||||
if(pkName) {
|
if (pkName) {
|
||||||
defaultType = foreignModel.properties[pkName].type;
|
defaultType = foreignModel.properties[pkName].type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1467,12 +1457,12 @@ DataSource.prototype.defineForeignKey = function defineForeignKey(className, key
|
||||||
DataSource.prototype.disconnect = function disconnect(cb) {
|
DataSource.prototype.disconnect = function disconnect(cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (this.connected && (typeof this.connector.disconnect === 'function')) {
|
if (this.connected && (typeof this.connector.disconnect === 'function')) {
|
||||||
this.connector.disconnect(function(err, result) {
|
this.connector.disconnect(function (err, result) {
|
||||||
self.connected = false;
|
self.connected = false;
|
||||||
cb && cb(err, result);
|
cb && cb(err, result);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
process.nextTick(function() {
|
process.nextTick(function () {
|
||||||
cb && cb();
|
cb && cb();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1526,7 +1516,7 @@ DataSource.prototype.copyModel = function copyModel(Master) {
|
||||||
* @returns {EventEmitter}
|
* @returns {EventEmitter}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.transaction = function() {
|
DataSource.prototype.transaction = function () {
|
||||||
var dataSource = this;
|
var dataSource = this;
|
||||||
var transaction = new EventEmitter();
|
var transaction = new EventEmitter();
|
||||||
|
|
||||||
|
@ -1551,7 +1541,7 @@ DataSource.prototype.transaction = function() {
|
||||||
dataSource.copyModel.call(transaction, dataSource.modelBuilder.models[i]);
|
dataSource.copyModel.call(transaction, dataSource.modelBuilder.models[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction.exec = function(cb) {
|
transaction.exec = function (cb) {
|
||||||
transaction.connector.exec(cb);
|
transaction.connector.exec(cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1565,7 +1555,7 @@ DataSource.prototype.transaction = function() {
|
||||||
|
|
||||||
DataSource.prototype.enableRemote = function (operation) {
|
DataSource.prototype.enableRemote = function (operation) {
|
||||||
var op = this.getOperation(operation);
|
var op = this.getOperation(operation);
|
||||||
if(op) {
|
if (op) {
|
||||||
op.remoteEnabled = true;
|
op.remoteEnabled = true;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(operation + ' is not provided by the attached connector');
|
throw new Error(operation + ' is not provided by the attached connector');
|
||||||
|
@ -1579,7 +1569,7 @@ DataSource.prototype.enableRemote = function (operation) {
|
||||||
|
|
||||||
DataSource.prototype.disableRemote = function (operation) {
|
DataSource.prototype.disableRemote = function (operation) {
|
||||||
var op = this.getOperation(operation);
|
var op = this.getOperation(operation);
|
||||||
if(op) {
|
if (op) {
|
||||||
op.remoteEnabled = false;
|
op.remoteEnabled = false;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(operation + ' is not provided by the attached connector');
|
throw new Error(operation + ' is not provided by the attached connector');
|
||||||
|
@ -1595,10 +1585,10 @@ DataSource.prototype.getOperation = function (operation) {
|
||||||
var ops = this.operations();
|
var ops = this.operations();
|
||||||
var opKeys = Object.keys(ops);
|
var opKeys = Object.keys(ops);
|
||||||
|
|
||||||
for(var i = 0; i < opKeys.length; i++) {
|
for (var i = 0; i < opKeys.length; i++) {
|
||||||
var op = ops[opKeys[i]];
|
var op = ops[opKeys[i]];
|
||||||
|
|
||||||
if(op.name === operation) {
|
if (op.name === operation) {
|
||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1627,7 +1617,7 @@ DataSource.prototype.defineOperation = function (name, options, fn) {
|
||||||
* Check if the backend is a relational DB
|
* Check if the backend is a relational DB
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.isRelational = function() {
|
DataSource.prototype.isRelational = function () {
|
||||||
return this.connector && this.connector.relational;
|
return this.connector && this.connector.relational;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1637,7 +1627,7 @@ DataSource.prototype.isRelational = function() {
|
||||||
* @param args
|
* @param args
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
DataSource.prototype.ready = function(obj, args) {
|
DataSource.prototype.ready = function (obj, args) {
|
||||||
var self = this;
|
var self = this;
|
||||||
if (this.connected) {
|
if (this.connected) {
|
||||||
// Connected
|
// Connected
|
||||||
|
@ -1658,7 +1648,7 @@ DataSource.prototype.ready = function(obj, args) {
|
||||||
self.removeListener('connected', onConnected);
|
self.removeListener('connected', onConnected);
|
||||||
var params = [].slice.call(args);
|
var params = [].slice.call(args);
|
||||||
var cb = params.pop();
|
var cb = params.pop();
|
||||||
if(typeof cb === 'function') {
|
if (typeof cb === 'function') {
|
||||||
cb(err);
|
cb(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1670,7 +1660,6 @@ DataSource.prototype.ready = function(obj, args) {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a hidden property
|
* Define a hidden property
|
||||||
* @param {Object} obj The property owner
|
* @param {Object} obj The property owner
|
||||||
|
@ -1702,7 +1691,6 @@ function defineReadonlyProp(obj, key, value) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Carry over a few properties/methods from the ModelBuilder as some tests use them
|
// Carry over a few properties/methods from the ModelBuilder as some tests use them
|
||||||
DataSource.Text = ModelBuilder.Text;
|
DataSource.Text = ModelBuilder.Text;
|
||||||
DataSource.JSON = ModelBuilder.JSON;
|
DataSource.JSON = ModelBuilder.JSON;
|
||||||
|
@ -1712,7 +1700,7 @@ DataSource.Any = ModelBuilder.Any;
|
||||||
* @deprecated Use ModelBuilder.registerType instead
|
* @deprecated Use ModelBuilder.registerType instead
|
||||||
* @param type
|
* @param type
|
||||||
*/
|
*/
|
||||||
DataSource.registerType = function(type) {
|
DataSource.registerType = function (type) {
|
||||||
ModelBuilder.registerType(type);
|
ModelBuilder.registerType(type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
36
lib/geo.js
36
lib/geo.js
|
@ -11,11 +11,11 @@ var assert = require('assert');
|
||||||
exports.nearFilter = function nearFilter(where) {
|
exports.nearFilter = function nearFilter(where) {
|
||||||
var result = false;
|
var result = false;
|
||||||
|
|
||||||
if(where && typeof where === 'object') {
|
if (where && typeof where === 'object') {
|
||||||
Object.keys(where).forEach(function (key) {
|
Object.keys(where).forEach(function (key) {
|
||||||
var ex = where[key];
|
var ex = where[key];
|
||||||
|
|
||||||
if(ex && ex.near) {
|
if (ex && ex.near) {
|
||||||
result = {
|
result = {
|
||||||
near: ex.near,
|
near: ex.near,
|
||||||
maxDistance: ex.maxDistance,
|
maxDistance: ex.maxDistance,
|
||||||
|
@ -45,18 +45,18 @@ exports.filter = function (arr, filter) {
|
||||||
var loc = obj[key];
|
var loc = obj[key];
|
||||||
|
|
||||||
// filter out objects without locations
|
// filter out objects without locations
|
||||||
if(!loc) return;
|
if (!loc) return;
|
||||||
|
|
||||||
if(!(loc instanceof GeoPoint)) {
|
if (!(loc instanceof GeoPoint)) {
|
||||||
loc = GeoPoint(loc);
|
loc = GeoPoint(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(typeof loc.lat !== 'number') return;
|
if (typeof loc.lat !== 'number') return;
|
||||||
if(typeof loc.lng !== 'number') return;
|
if (typeof loc.lng !== 'number') return;
|
||||||
|
|
||||||
var d = GeoPoint.distanceBetween(origin, loc);
|
var d = GeoPoint.distanceBetween(origin, loc);
|
||||||
|
|
||||||
if(max && d > max) {
|
if (max && d > max) {
|
||||||
// dont add
|
// dont add
|
||||||
} else {
|
} else {
|
||||||
distances[obj.id] = d;
|
distances[obj.id] = d;
|
||||||
|
@ -68,11 +68,11 @@ exports.filter = function (arr, filter) {
|
||||||
var a = objB[key];
|
var a = objB[key];
|
||||||
var b = objB[key];
|
var b = objB[key];
|
||||||
|
|
||||||
if(a && b) {
|
if (a && b) {
|
||||||
var da = distances[objA.id];
|
var da = distances[objA.id];
|
||||||
var db = distances[objB.id];
|
var db = distances[objB.id];
|
||||||
|
|
||||||
if(db === da) return 0;
|
if (db === da) return 0;
|
||||||
return da > db ? 1 : -1;
|
return da > db ? 1 : -1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -87,15 +87,15 @@ exports.filter = function (arr, filter) {
|
||||||
exports.GeoPoint = GeoPoint;
|
exports.GeoPoint = GeoPoint;
|
||||||
|
|
||||||
function GeoPoint(data) {
|
function GeoPoint(data) {
|
||||||
if(!(this instanceof GeoPoint)) {
|
if (!(this instanceof GeoPoint)) {
|
||||||
return new GeoPoint(data);
|
return new GeoPoint(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(typeof data === 'string') {
|
if (typeof data === 'string') {
|
||||||
data = data.split(/,\s*/);
|
data = data.split(/,\s*/);
|
||||||
assert(data.length === 2, 'must provide a string "lng,lat" creating a GeoPoint with a string');
|
assert(data.length === 2, 'must provide a string "lng,lat" creating a GeoPoint with a string');
|
||||||
}
|
}
|
||||||
if(Array.isArray(data)) {
|
if (Array.isArray(data)) {
|
||||||
data = {
|
data = {
|
||||||
lng: Number(data[0]),
|
lng: Number(data[0]),
|
||||||
lat: Number(data[1])
|
lat: Number(data[1])
|
||||||
|
@ -122,10 +122,10 @@ function GeoPoint(data) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GeoPoint.distanceBetween = function distanceBetween(a, b, options) {
|
GeoPoint.distanceBetween = function distanceBetween(a, b, options) {
|
||||||
if(!(a instanceof GeoPoint)) {
|
if (!(a instanceof GeoPoint)) {
|
||||||
a = GeoPoint(a);
|
a = GeoPoint(a);
|
||||||
}
|
}
|
||||||
if(!(b instanceof GeoPoint)) {
|
if (!(b instanceof GeoPoint)) {
|
||||||
b = GeoPoint(b);
|
b = GeoPoint(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,12 +184,12 @@ function geoDistance(x1, y1, x2, y2, options) {
|
||||||
x2 = x2 * DEG2RAD;
|
x2 = x2 * DEG2RAD;
|
||||||
y2 = y2 * DEG2RAD;
|
y2 = y2 * DEG2RAD;
|
||||||
|
|
||||||
var a = Math.pow(Math.sin(( y2-y1 ) / 2.0 ), 2);
|
var a = Math.pow(Math.sin(( y2 - y1 ) / 2.0), 2);
|
||||||
var b = Math.pow(Math.sin(( x2-x1 ) / 2.0 ), 2);
|
var b = Math.pow(Math.sin(( x2 - x1 ) / 2.0), 2);
|
||||||
var c = Math.sqrt( a + Math.cos( y2 ) * Math.cos( y1 ) * b );
|
var c = Math.sqrt(a + Math.cos(y2) * Math.cos(y1) * b);
|
||||||
|
|
||||||
var type = (options && options.type) || 'miles';
|
var type = (options && options.type) || 'miles';
|
||||||
|
|
||||||
return 2 * Math.asin( c ) * EARTH_RADIUS[type];
|
return 2 * Math.asin(c) * EARTH_RADIUS[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,10 @@ Hookable.afterDestroy = null;
|
||||||
// TODO: Evaluate https://github.com/bnoguchi/hooks-js/
|
// TODO: Evaluate https://github.com/bnoguchi/hooks-js/
|
||||||
Hookable.prototype.trigger = function trigger(actionName, work, data) {
|
Hookable.prototype.trigger = function trigger(actionName, work, data) {
|
||||||
var capitalizedName = capitalize(actionName);
|
var capitalizedName = capitalize(actionName);
|
||||||
var beforeHook = this.constructor["before" + capitalizedName] || this.constructor["pre" + capitalizedName];
|
var beforeHook = this.constructor["before" + capitalizedName]
|
||||||
var afterHook = this.constructor["after" + capitalizedName] || this.constructor["post" + capitalizedName];
|
|| this.constructor["pre" + capitalizedName];
|
||||||
|
var afterHook = this.constructor["after" + capitalizedName]
|
||||||
|
|| this.constructor["post" + capitalizedName];
|
||||||
if (actionName === 'validate') {
|
if (actionName === 'validate') {
|
||||||
beforeHook = beforeHook || this.constructor.beforeValidation;
|
beforeHook = beforeHook || this.constructor.beforeValidation;
|
||||||
afterHook = afterHook || this.constructor.afterValidation;
|
afterHook = afterHook || this.constructor.afterValidation;
|
||||||
|
|
|
@ -46,7 +46,7 @@ Inclusion.include = function (objects, include, cb) {
|
||||||
var callback = processIncludeItem(objects, include[i], keyVals, objsByKeys);
|
var callback = processIncludeItem(objects, include[i], keyVals, objsByKeys);
|
||||||
if (callback !== null) {
|
if (callback !== null) {
|
||||||
nbCallbacks++;
|
nbCallbacks++;
|
||||||
callback(function() {
|
callback(function () {
|
||||||
nbCallbacks--;
|
nbCallbacks--;
|
||||||
if (nbCallbacks == 0) {
|
if (nbCallbacks == 0) {
|
||||||
cb(null, objects);
|
cb(null, objects);
|
||||||
|
@ -86,8 +86,9 @@ Inclusion.include = function (objects, include, cb) {
|
||||||
var relation = relations[relationName];
|
var relation = relations[relationName];
|
||||||
|
|
||||||
if (!relation) {
|
if (!relation) {
|
||||||
return function() {
|
return function () {
|
||||||
cb(new Error('Relation "' + relationName + '" is not defined for ' + self.modelName + ' model'));
|
cb(new Error('Relation "' + relationName + '" is not defined for '
|
||||||
|
+ self.modelName + ' model'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ Inclusion.include = function (objects, include, cb) {
|
||||||
|
|
||||||
if (!keyVals[relation.keyFrom]) {
|
if (!keyVals[relation.keyFrom]) {
|
||||||
objsByKeys[relation.keyFrom] = {};
|
objsByKeys[relation.keyFrom] = {};
|
||||||
objs.filter(Boolean).forEach(function(obj) {
|
objs.filter(Boolean).forEach(function (obj) {
|
||||||
if (!objsByKeys[relation.keyFrom][obj[relation.keyFrom]]) {
|
if (!objsByKeys[relation.keyFrom][obj[relation.keyFrom]]) {
|
||||||
objsByKeys[relation.keyFrom][obj[relation.keyFrom]] = [];
|
objsByKeys[relation.keyFrom][obj[relation.keyFrom]] = [];
|
||||||
}
|
}
|
||||||
|
@ -110,7 +111,8 @@ Inclusion.include = function (objects, include, cb) {
|
||||||
var inValues = [];
|
var inValues = [];
|
||||||
for (var j = 0; j < keyVals[relation.keyFrom].length; j++) {
|
for (var j = 0; j < keyVals[relation.keyFrom].length; j++) {
|
||||||
keysToBeProcessed[keyVals[relation.keyFrom][j]] = true;
|
keysToBeProcessed[keyVals[relation.keyFrom][j]] = true;
|
||||||
if (keyVals[relation.keyFrom][j] !== 'null' && keyVals[relation.keyFrom][j] !== 'undefined') {
|
if (keyVals[relation.keyFrom][j] !== 'null'
|
||||||
|
&& keyVals[relation.keyFrom][j] !== 'undefined') {
|
||||||
inValues.push(keyVals[relation.keyFrom][j]);
|
inValues.push(keyVals[relation.keyFrom][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,8 +120,8 @@ Inclusion.include = function (objects, include, cb) {
|
||||||
req['where'][relation.keyTo] = {inq: inValues};
|
req['where'][relation.keyTo] = {inq: inValues};
|
||||||
req['include'] = subInclude;
|
req['include'] = subInclude;
|
||||||
|
|
||||||
return function(cb) {
|
return function (cb) {
|
||||||
relation.modelTo.find(req, function(err, objsIncluded) {
|
relation.modelTo.find(req, function (err, objsIncluded) {
|
||||||
for (var i = 0; i < objsIncluded.length; i++) {
|
for (var i = 0; i < objsIncluded.length; i++) {
|
||||||
delete keysToBeProcessed[objsIncluded[i][relation.keyTo]];
|
delete keysToBeProcessed[objsIncluded[i][relation.keyTo]];
|
||||||
var objectsFrom = objsByKeys[relation.keyFrom][objsIncluded[i][relation.keyTo]];
|
var objectsFrom = objsByKeys[relation.keyFrom][objsIncluded[i][relation.keyTo]];
|
||||||
|
@ -145,7 +147,8 @@ Inclusion.include = function (objects, include, cb) {
|
||||||
if (!objectsFrom[j].__cachedRelations) {
|
if (!objectsFrom[j].__cachedRelations) {
|
||||||
objectsFrom[j].__cachedRelations = {};
|
objectsFrom[j].__cachedRelations = {};
|
||||||
}
|
}
|
||||||
objectsFrom[j].__cachedRelations[relationName] = relation.multiple ? [] : null;
|
objectsFrom[j].__cachedRelations[relationName] =
|
||||||
|
relation.multiple ? [] : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cb(err, objsIncluded);
|
cb(err, objsIncluded);
|
||||||
|
@ -153,7 +156,6 @@ Inclusion.include = function (objects, include, cb) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
lib/jutil.js
28
lib/jutil.js
|
@ -14,7 +14,8 @@ exports.inherits = function (newClass, baseClass, options) {
|
||||||
|
|
||||||
if (options.staticProperties) {
|
if (options.staticProperties) {
|
||||||
Object.keys(baseClass).forEach(function (classProp) {
|
Object.keys(baseClass).forEach(function (classProp) {
|
||||||
if (classProp !== 'super_' && (!newClass.hasOwnProperty(classProp) || options.override)) {
|
if (classProp !== 'super_' && (!newClass.hasOwnProperty(classProp)
|
||||||
|
|| options.override)) {
|
||||||
var pd = Object.getOwnPropertyDescriptor(baseClass, classProp);
|
var pd = Object.getOwnPropertyDescriptor(baseClass, classProp);
|
||||||
Object.defineProperty(newClass, classProp, pd);
|
Object.defineProperty(newClass, classProp, pd);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +23,6 @@ exports.inherits = function (newClass, baseClass, options) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mix in the a class into the new class
|
* Mix in the a class into the new class
|
||||||
* @param newClass The target class to receive the mixin
|
* @param newClass The target class to receive the mixin
|
||||||
|
@ -31,7 +31,7 @@ exports.inherits = function (newClass, baseClass, options) {
|
||||||
*/
|
*/
|
||||||
exports.mixin = function (newClass, mixinClass, options) {
|
exports.mixin = function (newClass, mixinClass, options) {
|
||||||
if (Array.isArray(newClass._mixins)) {
|
if (Array.isArray(newClass._mixins)) {
|
||||||
if(newClass._mixins.indexOf(mixinClass) !== -1) {
|
if (newClass._mixins.indexOf(mixinClass) !== -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
newClass._mixins.push(mixinClass);
|
newClass._mixins.push(mixinClass);
|
||||||
|
@ -46,20 +46,22 @@ exports.mixin = function (newClass, mixinClass, options) {
|
||||||
proxyFunctions: false
|
proxyFunctions: false
|
||||||
};
|
};
|
||||||
|
|
||||||
if(options.staticProperties === undefined) {
|
if (options.staticProperties === undefined) {
|
||||||
options.staticProperties = true;
|
options.staticProperties = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(options.instanceProperties === undefined) {
|
if (options.instanceProperties === undefined) {
|
||||||
options.instanceProperties = true;
|
options.instanceProperties = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.staticProperties) {
|
if (options.staticProperties) {
|
||||||
var staticProxies = [];
|
var staticProxies = [];
|
||||||
Object.keys(mixinClass).forEach(function (classProp) {
|
Object.keys(mixinClass).forEach(function (classProp) {
|
||||||
if (classProp !== 'super_' && classProp !== '_mixins' && (!newClass.hasOwnProperty(classProp) || options.override)) {
|
if (classProp !== 'super_' && classProp !== '_mixins'
|
||||||
|
&& (!newClass.hasOwnProperty(classProp) || options.override)) {
|
||||||
var pd = Object.getOwnPropertyDescriptor(mixinClass, classProp);
|
var pd = Object.getOwnPropertyDescriptor(mixinClass, classProp);
|
||||||
if(options.proxyFunctions && pd.writable && typeof pd.value === 'function') {
|
if (options.proxyFunctions && pd.writable
|
||||||
|
&& typeof pd.value === 'function') {
|
||||||
pd.value = exports.proxy(pd.value, staticProxies);
|
pd.value = exports.proxy(pd.value, staticProxies);
|
||||||
}
|
}
|
||||||
Object.defineProperty(newClass, classProp, pd);
|
Object.defineProperty(newClass, classProp, pd);
|
||||||
|
@ -73,7 +75,7 @@ exports.mixin = function (newClass, mixinClass, options) {
|
||||||
Object.keys(mixinClass.prototype).forEach(function (instanceProp) {
|
Object.keys(mixinClass.prototype).forEach(function (instanceProp) {
|
||||||
if (!newClass.prototype.hasOwnProperty(instanceProp) || options.override) {
|
if (!newClass.prototype.hasOwnProperty(instanceProp) || options.override) {
|
||||||
var pd = Object.getOwnPropertyDescriptor(mixinClass.prototype, instanceProp);
|
var pd = Object.getOwnPropertyDescriptor(mixinClass.prototype, instanceProp);
|
||||||
if(options.proxyFunctions && pd.writable && typeof pd.value === 'function') {
|
if (options.proxyFunctions && pd.writable && typeof pd.value === 'function') {
|
||||||
pd.value = exports.proxy(pd.value, instanceProxies);
|
pd.value = exports.proxy(pd.value, instanceProxies);
|
||||||
}
|
}
|
||||||
Object.defineProperty(newClass.prototype, instanceProp, pd);
|
Object.defineProperty(newClass.prototype, instanceProp, pd);
|
||||||
|
@ -85,21 +87,21 @@ exports.mixin = function (newClass, mixinClass, options) {
|
||||||
return newClass;
|
return newClass;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.proxy = function(fn, proxies) {
|
exports.proxy = function (fn, proxies) {
|
||||||
// Make sure same methods referenced by different properties have the same proxy
|
// Make sure same methods referenced by different properties have the same proxy
|
||||||
// For example, deleteById is an alias of removeById
|
// For example, deleteById is an alias of removeById
|
||||||
proxies = proxies || [];
|
proxies = proxies || [];
|
||||||
for(var i = 0; i<proxies.length; i++) {
|
for (var i = 0; i < proxies.length; i++) {
|
||||||
if(proxies[i]._delegate === fn) {
|
if (proxies[i]._delegate === fn) {
|
||||||
return proxies[i];
|
return proxies[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var f = function() {
|
var f = function () {
|
||||||
return fn.apply(this, arguments);
|
return fn.apply(this, arguments);
|
||||||
};
|
};
|
||||||
f._delegate = fn;
|
f._delegate = fn;
|
||||||
proxies.push(f);
|
proxies.push(f);
|
||||||
Object.keys(fn).forEach(function(x) {
|
Object.keys(fn).forEach(function (x) {
|
||||||
f[x] = fn[x];
|
f[x] = fn[x];
|
||||||
});
|
});
|
||||||
return f;
|
return f;
|
||||||
|
|
45
lib/list.js
45
lib/list.js
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
module.exports = List;
|
module.exports = List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,10 +14,10 @@ function List(data, type, parent) {
|
||||||
return new List(data, type, parent);
|
return new List(data, type, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(typeof data === 'string') {
|
if (typeof data === 'string') {
|
||||||
try {
|
try {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
throw new Error('could not create List from JSON string: ', data);
|
throw new Error('could not create List from JSON string: ', data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +44,7 @@ function List(data, type, parent) {
|
||||||
Item = list.ItemType = type[0] || ListItem;
|
Item = list.ItemType = type[0] || ListItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.forEach(function(item, i) {
|
data.forEach(function (item, i) {
|
||||||
data[i] = Item(item, list);
|
data[i] = Item(item, list);
|
||||||
Object.defineProperty(list, data[i].id, {
|
Object.defineProperty(list, data[i].id, {
|
||||||
writable: true,
|
writable: true,
|
||||||
|
@ -61,7 +60,7 @@ function List(data, type, parent) {
|
||||||
Object.defineProperty(list, 'length', {
|
Object.defineProperty(list, 'length', {
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
configurable: true,
|
configurable: true,
|
||||||
get: function() {
|
get: function () {
|
||||||
return list.items.length;
|
return list.items.length;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -119,8 +118,8 @@ if (_) {
|
||||||
'range'
|
'range'
|
||||||
];
|
];
|
||||||
|
|
||||||
_import.forEach(function(name) {
|
_import.forEach(function (name) {
|
||||||
List.prototype[name] = function() {
|
List.prototype[name] = function () {
|
||||||
var args = [].slice.call(arguments);
|
var args = [].slice.call(arguments);
|
||||||
args.unshift(this.items);
|
args.unshift(this.items);
|
||||||
return _[name].apply(_, args);
|
return _[name].apply(_, args);
|
||||||
|
@ -135,10 +134,10 @@ if (_) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
List.prototype.find = function(pattern, field) {
|
List.prototype.find = function (pattern, field) {
|
||||||
if (field) {
|
if (field) {
|
||||||
var res;
|
var res;
|
||||||
this.items.forEach(function(o) {
|
this.items.forEach(function (o) {
|
||||||
if (o[field] == pattern) res = o;
|
if (o[field] == pattern) res = o;
|
||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
|
@ -147,10 +146,10 @@ List.prototype.find = function(pattern, field) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
List.prototype.toObject = function(onlySchema) {
|
List.prototype.toObject = function (onlySchema) {
|
||||||
var items = [];
|
var items = [];
|
||||||
this.items.forEach(function(item) {
|
this.items.forEach(function (item) {
|
||||||
if(item.toObject) {
|
if (item.toObject) {
|
||||||
items.push(item.toObject(onlySchema));
|
items.push(item.toObject(onlySchema));
|
||||||
} else {
|
} else {
|
||||||
items.push(item);
|
items.push(item);
|
||||||
|
@ -159,28 +158,28 @@ List.prototype.toObject = function(onlySchema) {
|
||||||
return items;
|
return items;
|
||||||
};
|
};
|
||||||
|
|
||||||
List.prototype.toJSON = function() {
|
List.prototype.toJSON = function () {
|
||||||
return this.toObject(true);
|
return this.toObject(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
List.prototype.toString = function() {
|
List.prototype.toString = function () {
|
||||||
return JSON.stringify(this.items);
|
return JSON.stringify(this.items);
|
||||||
};
|
};
|
||||||
|
|
||||||
List.prototype.autoincrement = function() {
|
List.prototype.autoincrement = function () {
|
||||||
return this.nextid++;
|
return this.nextid++;
|
||||||
};
|
};
|
||||||
|
|
||||||
List.prototype.push = function(obj) {
|
List.prototype.push = function (obj) {
|
||||||
var item = new ListItem(obj, this);
|
var item = new ListItem(obj, this);
|
||||||
this.items.push(item);
|
this.items.push(item);
|
||||||
return item;
|
return item;
|
||||||
};
|
};
|
||||||
|
|
||||||
List.prototype.remove = function(obj) {
|
List.prototype.remove = function (obj) {
|
||||||
var id = obj.id ? obj.id : obj;
|
var id = obj.id ? obj.id : obj;
|
||||||
var found = false;
|
var found = false;
|
||||||
this.items.forEach(function(o, i) {
|
this.items.forEach(function (o, i) {
|
||||||
if (id && o.id == id) {
|
if (id && o.id == id) {
|
||||||
found = i;
|
found = i;
|
||||||
if (o.id !== id) {
|
if (o.id !== id) {
|
||||||
|
@ -194,20 +193,20 @@ List.prototype.remove = function(obj) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
List.prototype.sort = function(cb) {
|
List.prototype.sort = function (cb) {
|
||||||
return this.items.sort(cb);
|
return this.items.sort(cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
List.prototype.map = function(cb) {
|
List.prototype.map = function (cb) {
|
||||||
if (typeof cb === 'function') return this.items.map(cb);
|
if (typeof cb === 'function') return this.items.map(cb);
|
||||||
if (typeof cb === 'string') return this.items.map(function(el) {
|
if (typeof cb === 'string') return this.items.map(function (el) {
|
||||||
if (typeof el[cb] === 'function') return el[cb]();
|
if (typeof el[cb] === 'function') return el[cb]();
|
||||||
if (el.hasOwnProperty(cb)) return el[cb];
|
if (el.hasOwnProperty(cb)) return el[cb];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function ListItem(data, parent) {
|
function ListItem(data, parent) {
|
||||||
if(!(this instanceof ListItem)) {
|
if (!(this instanceof ListItem)) {
|
||||||
return new ListItem(data, parent);
|
return new ListItem(data, parent);
|
||||||
}
|
}
|
||||||
if (typeof data === 'object') {
|
if (typeof data === 'object') {
|
||||||
|
@ -231,7 +230,7 @@ function ListItem(data, parent) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.save = function(c) {
|
this.save = function (c) {
|
||||||
parent.parent.save(c);
|
parent.parent.save(c);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ util.inherits(ModelBuilder, EventEmitter);
|
||||||
ModelBuilder.defaultInstance = new ModelBuilder();
|
ModelBuilder.defaultInstance = new ModelBuilder();
|
||||||
|
|
||||||
function isModelClass(cls) {
|
function isModelClass(cls) {
|
||||||
if(!cls) {
|
if (!cls) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return cls.prototype instanceof DefaultModelBaseClass;
|
return cls.prototype instanceof DefaultModelBaseClass;
|
||||||
|
@ -63,15 +63,15 @@ function isModelClass(cls) {
|
||||||
* given name if a model doesn't exist
|
* given name if a model doesn't exist
|
||||||
* @returns {*} The model class
|
* @returns {*} The model class
|
||||||
*/
|
*/
|
||||||
ModelBuilder.prototype.getModel = function(name, forceCreate) {
|
ModelBuilder.prototype.getModel = function (name, forceCreate) {
|
||||||
var model = this.models[name];
|
var model = this.models[name];
|
||||||
if(!model && forceCreate) {
|
if (!model && forceCreate) {
|
||||||
model = this.define(name, {}, {unresolved: true});
|
model = this.define(name, {}, {unresolved: true});
|
||||||
}
|
}
|
||||||
return model;
|
return model;
|
||||||
};
|
};
|
||||||
|
|
||||||
ModelBuilder.prototype.getModelDefinition = function(name) {
|
ModelBuilder.prototype.getModelDefinition = function (name) {
|
||||||
return this.definitions[name];
|
return this.definitions[name];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -128,15 +128,15 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
settings = settings || {};
|
settings = settings || {};
|
||||||
|
|
||||||
// Set the strict mode to be false by default
|
// Set the strict mode to be false by default
|
||||||
if(settings.strict === undefined || settings.strict === null) {
|
if (settings.strict === undefined || settings.strict === null) {
|
||||||
settings.strict = false;
|
settings.strict = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the base model class
|
// Set up the base model class
|
||||||
var ModelBaseClass = parent || DefaultModelBaseClass;
|
var ModelBaseClass = parent || DefaultModelBaseClass;
|
||||||
var baseClass = settings.base || settings['super'];
|
var baseClass = settings.base || settings['super'];
|
||||||
if(baseClass) {
|
if (baseClass) {
|
||||||
if(isModelClass(baseClass)) {
|
if (isModelClass(baseClass)) {
|
||||||
ModelBaseClass = baseClass;
|
ModelBaseClass = baseClass;
|
||||||
} else {
|
} else {
|
||||||
ModelBaseClass = this.models[baseClass];
|
ModelBaseClass = this.models[baseClass];
|
||||||
|
@ -149,17 +149,17 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
|
|
||||||
// Create the ModelClass if it doesn't exist or it's resolved (override)
|
// Create the ModelClass if it doesn't exist or it's resolved (override)
|
||||||
// TODO: [rfeng] We need to decide what names to use for built-in models such as User.
|
// TODO: [rfeng] We need to decide what names to use for built-in models such as User.
|
||||||
if(!ModelClass || !ModelClass.settings.unresolved) {
|
if (!ModelClass || !ModelClass.settings.unresolved) {
|
||||||
// every class can receive hash of data as optional param
|
// every class can receive hash of data as optional param
|
||||||
ModelClass = function ModelConstructor(data, dataSource) {
|
ModelClass = function ModelConstructor(data, dataSource) {
|
||||||
if(!(this instanceof ModelConstructor)) {
|
if (!(this instanceof ModelConstructor)) {
|
||||||
return new ModelConstructor(data, dataSource);
|
return new ModelConstructor(data, dataSource);
|
||||||
}
|
}
|
||||||
if(ModelClass.settings.unresolved) {
|
if (ModelClass.settings.unresolved) {
|
||||||
throw new Error('Model ' + ModelClass.modelName + ' is not defined.');
|
throw new Error('Model ' + ModelClass.modelName + ' is not defined.');
|
||||||
}
|
}
|
||||||
ModelBaseClass.apply(this, arguments);
|
ModelBaseClass.apply(this, arguments);
|
||||||
if(dataSource) {
|
if (dataSource) {
|
||||||
hiddenProperty(this, '__dataSource', dataSource);
|
hiddenProperty(this, '__dataSource', dataSource);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -179,7 +179,7 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
this.models[className] = ModelClass;
|
this.models[className] = ModelClass;
|
||||||
|
|
||||||
// Return the unresolved model
|
// Return the unresolved model
|
||||||
if(settings.unresolved) {
|
if (settings.unresolved) {
|
||||||
ModelClass.settings = {unresolved: true};
|
ModelClass.settings = {unresolved: true};
|
||||||
return ModelClass;
|
return ModelClass;
|
||||||
}
|
}
|
||||||
|
@ -194,14 +194,14 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
// inherit ModelBaseClass static methods
|
// inherit ModelBaseClass static methods
|
||||||
for (var i in ModelBaseClass) {
|
for (var i in ModelBaseClass) {
|
||||||
// We need to skip properties that are already in the subclass, for example, the event emitter methods
|
// We need to skip properties that are already in the subclass, for example, the event emitter methods
|
||||||
if(i !== '_mixins' && !(i in ModelClass)) {
|
if (i !== '_mixins' && !(i in ModelClass)) {
|
||||||
ModelClass[i] = ModelBaseClass[i];
|
ModelClass[i] = ModelBaseClass[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load and inject the model classes
|
// Load and inject the model classes
|
||||||
if(settings.models) {
|
if (settings.models) {
|
||||||
Object.keys(settings.models).forEach(function(m) {
|
Object.keys(settings.models).forEach(function (m) {
|
||||||
var model = settings.models[m];
|
var model = settings.models[m];
|
||||||
ModelClass[m] = typeof model === 'string' ? modelBuilder.getModel(model, true) : model;
|
ModelClass[m] = typeof model === 'string' ? modelBuilder.getModel(model, true) : model;
|
||||||
});
|
});
|
||||||
|
@ -220,13 +220,13 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
ModelClass.settings = modelDefinition.settings;
|
ModelClass.settings = modelDefinition.settings;
|
||||||
|
|
||||||
var idInjection = settings.idInjection;
|
var idInjection = settings.idInjection;
|
||||||
if(idInjection !== false) {
|
if (idInjection !== false) {
|
||||||
// Default to true if undefined
|
// Default to true if undefined
|
||||||
idInjection = true;
|
idInjection = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var idNames = modelDefinition.idNames();
|
var idNames = modelDefinition.idNames();
|
||||||
if(idNames.length > 0) {
|
if (idNames.length > 0) {
|
||||||
// id already exists
|
// id already exists
|
||||||
idInjection = false;
|
idInjection = false;
|
||||||
}
|
}
|
||||||
|
@ -287,8 +287,8 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
|
|
||||||
// Check if subclass redefines the ids
|
// Check if subclass redefines the ids
|
||||||
var idFound = false;
|
var idFound = false;
|
||||||
for(var k in subclassProperties) {
|
for (var k in subclassProperties) {
|
||||||
if(subclassProperties[k].id) {
|
if (subclassProperties[k].id) {
|
||||||
idFound = true;
|
idFound = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -296,11 +296,11 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
|
|
||||||
// Merging the properties
|
// Merging the properties
|
||||||
Object.keys(properties).forEach(function (key) {
|
Object.keys(properties).forEach(function (key) {
|
||||||
if(idFound && properties[key].id) {
|
if (idFound && properties[key].id) {
|
||||||
// don't inherit id properties
|
// don't inherit id properties
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(subclassProperties[key] === undefined) {
|
if (subclassProperties[key] === undefined) {
|
||||||
subclassProperties[key] = properties[key];
|
subclassProperties[key] = properties[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -320,7 +320,7 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
var subClass = modelBuilder.define(className, subclassProperties, subclassSettings, ModelClass);
|
var subClass = modelBuilder.define(className, subclassProperties, subclassSettings, ModelClass);
|
||||||
|
|
||||||
// Calling the setup function
|
// Calling the setup function
|
||||||
if(typeof subClass.setup === 'function') {
|
if (typeof subClass.setup === 'function') {
|
||||||
subClass.setup.call(subClass);
|
subClass.setup.call(subClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
var properties = modelDefinition.build();
|
var properties = modelDefinition.build();
|
||||||
var prop = properties[propertyName];
|
var prop = properties[propertyName];
|
||||||
var DataType = prop.type;
|
var DataType = prop.type;
|
||||||
if(!DataType) {
|
if (!DataType) {
|
||||||
throw new Error('Invalid type for property ' + propertyName);
|
throw new Error('Invalid type for property ' + propertyName);
|
||||||
}
|
}
|
||||||
if (Array.isArray(DataType) || DataType === Array) {
|
if (Array.isArray(DataType) || DataType === Array) {
|
||||||
|
@ -345,11 +345,11 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
DataType = function Date(arg) {
|
DataType = function Date(arg) {
|
||||||
return new OrigDate(arg);
|
return new OrigDate(arg);
|
||||||
};
|
};
|
||||||
} else if(typeof DataType === 'string') {
|
} else if (typeof DataType === 'string') {
|
||||||
DataType = modelBuilder.resolveType(DataType);
|
DataType = modelBuilder.resolveType(DataType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(prop.required) {
|
if (prop.required) {
|
||||||
var requiredOptions = typeof prop.required === 'object' ? prop.required : undefined;
|
var requiredOptions = typeof prop.required === 'object' ? prop.required : undefined;
|
||||||
ModelClass.validatesPresenceOf(propertyName, requiredOptions);
|
ModelClass.validatesPresenceOf(propertyName, requiredOptions);
|
||||||
}
|
}
|
||||||
|
@ -372,7 +372,7 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
|
||||||
if (value === null || value === undefined) {
|
if (value === null || value === undefined) {
|
||||||
this.__data[propertyName] = value;
|
this.__data[propertyName] = value;
|
||||||
} else {
|
} else {
|
||||||
if(DataType === List) {
|
if (DataType === List) {
|
||||||
this.__data[propertyName] = DataType(value, properties[propertyName].type, this.__data);
|
this.__data[propertyName] = DataType(value, properties[propertyName].type, this.__data);
|
||||||
} else {
|
} else {
|
||||||
// Assume the type constructor handles Constructor() call
|
// Assume the type constructor handles Constructor() call
|
||||||
|
@ -463,7 +463,6 @@ ModelBuilder.prototype.extendModel = function (model, props) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ModelBuilder.prototype.copyModel = function copyModel(Master) {
|
ModelBuilder.prototype.copyModel = function copyModel(Master) {
|
||||||
var modelBuilder = this;
|
var modelBuilder = this;
|
||||||
var className = Master.modelName;
|
var className = Master.modelName;
|
||||||
|
@ -493,7 +492,6 @@ ModelBuilder.prototype.copyModel = function copyModel(Master) {
|
||||||
return Slave;
|
return Slave;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Define hidden property
|
* Define hidden property
|
||||||
*/
|
*/
|
||||||
|
@ -526,7 +524,7 @@ ModelBuilder.prototype.getSchemaName = function (name) {
|
||||||
* @param {String} type The type string, such as 'number', 'Number', 'boolean', or 'String'. It's case insensitive
|
* @param {String} type The type string, such as 'number', 'Number', 'boolean', or 'String'. It's case insensitive
|
||||||
* @returns {Function} if the type is resolved
|
* @returns {Function} if the type is resolved
|
||||||
*/
|
*/
|
||||||
ModelBuilder.prototype.resolveType = function(type) {
|
ModelBuilder.prototype.resolveType = function (type) {
|
||||||
if (!type) {
|
if (!type) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -557,7 +555,7 @@ ModelBuilder.prototype.resolveType = function(type) {
|
||||||
return this.define(this.getSchemaName(null),
|
return this.define(this.getSchemaName(null),
|
||||||
type, {anonymous: true, idInjection: false});
|
type, {anonymous: true, idInjection: false});
|
||||||
}
|
}
|
||||||
} else if('function' === typeof type ) {
|
} else if ('function' === typeof type) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
|
@ -610,7 +608,7 @@ ModelBuilder.prototype.buildModels = function (schemas) {
|
||||||
var sourceModel = models[relation.source];
|
var sourceModel = models[relation.source];
|
||||||
var targetModel = models[relation.target];
|
var targetModel = models[relation.target];
|
||||||
if (sourceModel && targetModel) {
|
if (sourceModel && targetModel) {
|
||||||
if(typeof sourceModel[relation.type] === 'function') {
|
if (typeof sourceModel[relation.type] === 'function') {
|
||||||
sourceModel[relation.type](targetModel, {as: relation.as});
|
sourceModel[relation.type](targetModel, {as: relation.as});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -625,7 +623,7 @@ ModelBuilder.prototype.buildModels = function (schemas) {
|
||||||
* @param [Object} options The options
|
* @param [Object} options The options
|
||||||
* @returns {}
|
* @returns {}
|
||||||
*/
|
*/
|
||||||
ModelBuilder.prototype.buildModelFromInstance = function(name, json, options) {
|
ModelBuilder.prototype.buildModelFromInstance = function (name, json, options) {
|
||||||
|
|
||||||
// Introspect the JSON document to generate a schema
|
// Introspect the JSON document to generate a schema
|
||||||
var schema = introspect(json);
|
var schema = introspect(json);
|
||||||
|
|
|
@ -49,14 +49,13 @@ util.inherits(ModelDefinition, EventEmitter);
|
||||||
// Set up types
|
// Set up types
|
||||||
require('./types')(ModelDefinition);
|
require('./types')(ModelDefinition);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return table name for specified `modelName`
|
* Return table name for specified `modelName`
|
||||||
* @param {String} connectorType The connector type, such as 'oracle' or 'mongodb'
|
* @param {String} connectorType The connector type, such as 'oracle' or 'mongodb'
|
||||||
*/
|
*/
|
||||||
ModelDefinition.prototype.tableName = function (connectorType) {
|
ModelDefinition.prototype.tableName = function (connectorType) {
|
||||||
var settings = this.settings;
|
var settings = this.settings;
|
||||||
if(settings[connectorType]) {
|
if (settings[connectorType]) {
|
||||||
return settings[connectorType].table || settings[connectorType].tableName || this.name;
|
return settings[connectorType].table || settings[connectorType].tableName || this.name;
|
||||||
} else {
|
} else {
|
||||||
return this.name;
|
return this.name;
|
||||||
|
@ -70,12 +69,12 @@ ModelDefinition.prototype.tableName = function (connectorType) {
|
||||||
* @returns {String} columnName
|
* @returns {String} columnName
|
||||||
*/
|
*/
|
||||||
ModelDefinition.prototype.columnName = function (connectorType, propertyName) {
|
ModelDefinition.prototype.columnName = function (connectorType, propertyName) {
|
||||||
if(!propertyName) {
|
if (!propertyName) {
|
||||||
return propertyName;
|
return propertyName;
|
||||||
}
|
}
|
||||||
this.build();
|
this.build();
|
||||||
var property = this.properties[propertyName];
|
var property = this.properties[propertyName];
|
||||||
if(property && property[connectorType]) {
|
if (property && property[connectorType]) {
|
||||||
return property[connectorType].column || property[connectorType].columnName || propertyName;
|
return property[connectorType].column || property[connectorType].columnName || propertyName;
|
||||||
} else {
|
} else {
|
||||||
return propertyName;
|
return propertyName;
|
||||||
|
@ -89,12 +88,12 @@ ModelDefinition.prototype.columnName = function (connectorType, propertyName) {
|
||||||
* @returns {Object} column metadata
|
* @returns {Object} column metadata
|
||||||
*/
|
*/
|
||||||
ModelDefinition.prototype.columnMetadata = function (connectorType, propertyName) {
|
ModelDefinition.prototype.columnMetadata = function (connectorType, propertyName) {
|
||||||
if(!propertyName) {
|
if (!propertyName) {
|
||||||
return propertyName;
|
return propertyName;
|
||||||
}
|
}
|
||||||
this.build();
|
this.build();
|
||||||
var property = this.properties[propertyName];
|
var property = this.properties[propertyName];
|
||||||
if(property && property[connectorType]) {
|
if (property && property[connectorType]) {
|
||||||
return property[connectorType];
|
return property[connectorType];
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -110,8 +109,8 @@ ModelDefinition.prototype.columnNames = function (connectorType) {
|
||||||
this.build();
|
this.build();
|
||||||
var props = this.properties;
|
var props = this.properties;
|
||||||
var cols = [];
|
var cols = [];
|
||||||
for(var p in props) {
|
for (var p in props) {
|
||||||
if(props[p][connectorType]) {
|
if (props[p][connectorType]) {
|
||||||
cols.push(property[connectorType].column || props[p][connectorType].columnName || p);
|
cols.push(property[connectorType].column || props[p][connectorType].columnName || p);
|
||||||
} else {
|
} else {
|
||||||
cols.push(p);
|
cols.push(p);
|
||||||
|
@ -125,7 +124,7 @@ ModelDefinition.prototype.columnNames = function (connectorType) {
|
||||||
* @returns {Object[]} property name/index for IDs
|
* @returns {Object[]} property name/index for IDs
|
||||||
*/
|
*/
|
||||||
ModelDefinition.prototype.ids = function () {
|
ModelDefinition.prototype.ids = function () {
|
||||||
if(this._ids) {
|
if (this._ids) {
|
||||||
return this._ids;
|
return this._ids;
|
||||||
}
|
}
|
||||||
var ids = [];
|
var ids = [];
|
||||||
|
@ -133,10 +132,10 @@ ModelDefinition.prototype.ids = function () {
|
||||||
var props = this.properties;
|
var props = this.properties;
|
||||||
for (var key in props) {
|
for (var key in props) {
|
||||||
var id = props[key].id;
|
var id = props[key].id;
|
||||||
if(!id) {
|
if (!id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(typeof id !== 'number') {
|
if (typeof id !== 'number') {
|
||||||
id = 1;
|
id = 1;
|
||||||
}
|
}
|
||||||
ids.push({name: key, id: id});
|
ids.push({name: key, id: id});
|
||||||
|
@ -153,7 +152,7 @@ ModelDefinition.prototype.ids = function () {
|
||||||
* @param {String} modelName The model name
|
* @param {String} modelName The model name
|
||||||
* @returns {String} columnName for ID
|
* @returns {String} columnName for ID
|
||||||
*/
|
*/
|
||||||
ModelDefinition.prototype.idColumnName = function(connectorType) {
|
ModelDefinition.prototype.idColumnName = function (connectorType) {
|
||||||
return this.columnName(connectorType, this.idName());
|
return this.columnName(connectorType, this.idName());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,11 +160,12 @@ ModelDefinition.prototype.idColumnName = function(connectorType) {
|
||||||
* Find the ID property name
|
* Find the ID property name
|
||||||
* @returns {String} property name for ID
|
* @returns {String} property name for ID
|
||||||
*/
|
*/
|
||||||
ModelDefinition.prototype.idName = function() {
|
ModelDefinition.prototype.idName = function () {
|
||||||
var id = this.ids()[0];
|
var id = this.ids()[0];
|
||||||
if(this.properties.id && this.properties.id.id) {
|
if (this.properties.id && this.properties.id.id) {
|
||||||
return 'id';
|
return 'id';
|
||||||
} else {}
|
} else {
|
||||||
|
}
|
||||||
return id && id.name;
|
return id && id.name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ ModelDefinition.prototype.indexes = function () {
|
||||||
* @param {Boolean} force Forcing rebuild
|
* @param {Boolean} force Forcing rebuild
|
||||||
*/
|
*/
|
||||||
ModelDefinition.prototype.build = function (forceRebuild) {
|
ModelDefinition.prototype.build = function (forceRebuild) {
|
||||||
if(forceRebuild) {
|
if (forceRebuild) {
|
||||||
this.properties = null;
|
this.properties = null;
|
||||||
this.relations = [];
|
this.relations = [];
|
||||||
this._ids = null;
|
this._ids = null;
|
||||||
|
@ -253,19 +253,18 @@ ModelDefinition.prototype.defineProperty = function (propertyName, propertyDefin
|
||||||
this.build(true);
|
this.build(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function isModelClass(cls) {
|
function isModelClass(cls) {
|
||||||
if(!cls) {
|
if (!cls) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return cls.prototype instanceof ModelBaseClass;
|
return cls.prototype instanceof ModelBaseClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelDefinition.prototype.toJSON = function(forceRebuild) {
|
ModelDefinition.prototype.toJSON = function (forceRebuild) {
|
||||||
if(forceRebuild) {
|
if (forceRebuild) {
|
||||||
this.json = null;
|
this.json = null;
|
||||||
}
|
}
|
||||||
if(this.json) {
|
if (this.json) {
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
var json = {
|
var json = {
|
||||||
|
@ -275,17 +274,17 @@ ModelDefinition.prototype.toJSON = function(forceRebuild) {
|
||||||
};
|
};
|
||||||
this.build(forceRebuild);
|
this.build(forceRebuild);
|
||||||
|
|
||||||
var mapper = function(val) {
|
var mapper = function (val) {
|
||||||
if(val === undefined || val === null) {
|
if (val === undefined || val === null) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
if('function' === typeof val.toJSON) {
|
if ('function' === typeof val.toJSON) {
|
||||||
// The value has its own toJSON() object
|
// The value has its own toJSON() object
|
||||||
return val.toJSON();
|
return val.toJSON();
|
||||||
}
|
}
|
||||||
if('function' === typeof val) {
|
if ('function' === typeof val) {
|
||||||
if(isModelClass(val)) {
|
if (isModelClass(val)) {
|
||||||
if(val.settings && val.settings.anonymous) {
|
if (val.settings && val.settings.anonymous) {
|
||||||
return val.definition && val.definition.toJSON().properties;
|
return val.definition && val.definition.toJSON().properties;
|
||||||
} else {
|
} else {
|
||||||
return val.modelName;
|
return val.modelName;
|
||||||
|
@ -296,7 +295,7 @@ ModelDefinition.prototype.toJSON = function(forceRebuild) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for(var p in this.properties) {
|
for (var p in this.properties) {
|
||||||
json.properties[p] = traverse(this.properties[p]).map(mapper);
|
json.properties[p] = traverse(this.properties[p]).map(mapper);
|
||||||
}
|
}
|
||||||
this.json = json;
|
this.json = json;
|
||||||
|
|
30
lib/model.js
30
lib/model.js
|
@ -90,26 +90,26 @@ ModelBaseClass.prototype._initProperties = function (data, applySetters) {
|
||||||
this.__data[ctor.relations[i].keyFrom] = this.__dataWas[i] = data[i][ctor.relations[i].keyTo];
|
this.__data[ctor.relations[i].keyFrom] = this.__dataWas[i] = data[i][ctor.relations[i].keyTo];
|
||||||
this.__cachedRelations[i] = data[i];
|
this.__cachedRelations[i] = data[i];
|
||||||
} else {
|
} else {
|
||||||
if(strict === false) {
|
if (strict === false) {
|
||||||
this.__data[i] = this.__dataWas[i] = clone(data[i]);
|
this.__data[i] = this.__dataWas[i] = clone(data[i]);
|
||||||
} else if(strict === 'throw') {
|
} else if (strict === 'throw') {
|
||||||
throw new Error('Unknown property: ' + i);
|
throw new Error('Unknown property: ' + i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applySetters === true) {
|
if (applySetters === true) {
|
||||||
for(var propertyName in data) {
|
for (var propertyName in data) {
|
||||||
if((propertyName in properties) || (propertyName in ctor.relations)) {
|
if ((propertyName in properties) || (propertyName in ctor.relations)) {
|
||||||
self[propertyName] = self.__data[propertyName] || data[propertyName];
|
self[propertyName] = self.__data[propertyName] || data[propertyName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the unknown properties as properties to the object
|
// Set the unknown properties as properties to the object
|
||||||
if(strict === false) {
|
if (strict === false) {
|
||||||
for(var propertyName in data) {
|
for (var propertyName in data) {
|
||||||
if(!(propertyName in properties)) {
|
if (!(propertyName in properties)) {
|
||||||
self[propertyName] = self.__data[propertyName] || data[propertyName];
|
self[propertyName] = self.__data[propertyName] || data[propertyName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ ModelBaseClass.prototype._initProperties = function (data, applySetters) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type.name === 'Array' || Array.isArray(type)) {
|
if (type.name === 'Array' || Array.isArray(type)) {
|
||||||
if(!(self.__data[propertyName] instanceof List)) {
|
if (!(self.__data[propertyName] instanceof List)) {
|
||||||
self.__data[propertyName] = new List(self.__data[propertyName], type, self);
|
self.__data[propertyName] = new List(self.__data[propertyName], type, self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,7 +172,7 @@ ModelBaseClass.defineProperty = function (prop, params) {
|
||||||
|
|
||||||
ModelBaseClass.getPropertyType = function (propName) {
|
ModelBaseClass.getPropertyType = function (propName) {
|
||||||
var prop = this.definition.properties[propName];
|
var prop = this.definition.properties[propName];
|
||||||
if(!prop) {
|
if (!prop) {
|
||||||
// The property is not part of the definition
|
// The property is not part of the definition
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ ModelBaseClass.prototype.toObject = function (onlySchema) {
|
||||||
if (self[propertyName] instanceof List) {
|
if (self[propertyName] instanceof List) {
|
||||||
data[propertyName] = self[propertyName].toObject(!schemaLess);
|
data[propertyName] = self[propertyName].toObject(!schemaLess);
|
||||||
} else if (self.__data.hasOwnProperty(propertyName)) {
|
} else if (self.__data.hasOwnProperty(propertyName)) {
|
||||||
if(self[propertyName] !== undefined && self[propertyName]!== null && self[propertyName].toObject) {
|
if (self[propertyName] !== undefined && self[propertyName] !== null && self[propertyName].toObject) {
|
||||||
data[propertyName] = self[propertyName].toObject(!schemaLess);
|
data[propertyName] = self[propertyName].toObject(!schemaLess);
|
||||||
} else {
|
} else {
|
||||||
data[propertyName] = self[propertyName];
|
data[propertyName] = self[propertyName];
|
||||||
|
@ -224,10 +224,10 @@ ModelBaseClass.prototype.toObject = function (onlySchema) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (schemaLess) {
|
if (schemaLess) {
|
||||||
for(var propertyName in self.__data) {
|
for (var propertyName in self.__data) {
|
||||||
if (!data.hasOwnProperty(propertyName)) {
|
if (!data.hasOwnProperty(propertyName)) {
|
||||||
var val = self.hasOwnProperty(propertyName) ? self[propertyName] : self.__data[propertyName];
|
var val = self.hasOwnProperty(propertyName) ? self[propertyName] : self.__data[propertyName];
|
||||||
if(val !== undefined && val!== null && val.toObject) {
|
if (val !== undefined && val !== null && val.toObject) {
|
||||||
data[propertyName] = val.toObject(!schemaLess);
|
data[propertyName] = val.toObject(!schemaLess);
|
||||||
} else {
|
} else {
|
||||||
data[propertyName] = val;
|
data[propertyName] = val;
|
||||||
|
@ -248,7 +248,7 @@ ModelBaseClass.prototype.toJSON = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
ModelBaseClass.prototype.fromObject = function (obj) {
|
ModelBaseClass.prototype.fromObject = function (obj) {
|
||||||
for(var key in obj) {
|
for (var key in obj) {
|
||||||
this[key] = obj[key];
|
this[key] = obj[key];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -271,7 +271,7 @@ ModelBaseClass.prototype.propertyChanged = function propertyChanged(propertyName
|
||||||
*/
|
*/
|
||||||
ModelBaseClass.prototype.reset = function () {
|
ModelBaseClass.prototype.reset = function () {
|
||||||
var obj = this;
|
var obj = this;
|
||||||
for(var k in obj) {
|
for (var k in obj) {
|
||||||
if (k !== 'id' && !obj.constructor.dataSource.definitions[obj.constructor.modelName].properties[k]) {
|
if (k !== 'id' && !obj.constructor.dataSource.definitions[obj.constructor.modelName].properties[k]) {
|
||||||
delete obj[k];
|
delete obj[k];
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ ModelBaseClass.prototype.inspect = function () {
|
||||||
return util.inspect(this.__data, false, 4, true);
|
return util.inspect(this.__data, false, 4, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
ModelBaseClass.mixin = function(anotherClass, options) {
|
ModelBaseClass.mixin = function (anotherClass, options) {
|
||||||
return jutil.mixin(this, anotherClass, options);
|
return jutil.mixin(this, anotherClass, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ Relation.hasMany = function hasMany(anotherClass, params) {
|
||||||
anotherClass = params.model;
|
anotherClass = params.model;
|
||||||
} else {
|
} else {
|
||||||
var anotherClassName = i8n.singularize(anotherClass).toLowerCase();
|
var anotherClassName = i8n.singularize(anotherClass).toLowerCase();
|
||||||
for(var name in this.dataSource.modelBuilder.models) {
|
for (var name in this.dataSource.modelBuilder.models) {
|
||||||
if (name.toLowerCase() === anotherClassName) {
|
if (name.toLowerCase() === anotherClassName) {
|
||||||
anotherClass = this.dataSource.modelBuilder.models[name];
|
anotherClass = this.dataSource.modelBuilder.models[name];
|
||||||
}
|
}
|
||||||
|
@ -68,17 +68,18 @@ Relation.hasMany = function hasMany(anotherClass, params) {
|
||||||
data = {};
|
data = {};
|
||||||
}
|
}
|
||||||
if ('function' !== typeof done) {
|
if ('function' !== typeof done) {
|
||||||
done = function() {};
|
done = function () {
|
||||||
|
};
|
||||||
}
|
}
|
||||||
var self = this;
|
var self = this;
|
||||||
anotherClass.create(data, function(err, ac) {
|
anotherClass.create(data, function (err, ac) {
|
||||||
if (err) return done(err, ac);
|
if (err) return done(err, ac);
|
||||||
var d = {};
|
var d = {};
|
||||||
d[params.through.relationNameFor(fk)] = self;
|
d[params.through.relationNameFor(fk)] = self;
|
||||||
d[params.through.relationNameFor(fk2)] = ac;
|
d[params.through.relationNameFor(fk2)] = ac;
|
||||||
params.through.create(d, function(e) {
|
params.through.create(d, function (e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
ac.destroy(function() {
|
ac.destroy(function () {
|
||||||
done(e);
|
done(e);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -87,7 +88,7 @@ Relation.hasMany = function hasMany(anotherClass, params) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
scopeMethods.add = function(acInst, done) {
|
scopeMethods.add = function (acInst, done) {
|
||||||
var data = {};
|
var data = {};
|
||||||
var query = {};
|
var query = {};
|
||||||
query[fk] = this[idName];
|
query[fk] = this[idName];
|
||||||
|
@ -96,10 +97,10 @@ Relation.hasMany = function hasMany(anotherClass, params) {
|
||||||
data[params.through.relationNameFor(fk2)] = acInst;
|
data[params.through.relationNameFor(fk2)] = acInst;
|
||||||
params.through.findOrCreate({where: query}, data, done);
|
params.through.findOrCreate({where: query}, data, done);
|
||||||
};
|
};
|
||||||
scopeMethods.remove = function(acInst, done) {
|
scopeMethods.remove = function (acInst, done) {
|
||||||
var q = {};
|
var q = {};
|
||||||
q[fk2] = acInst[idName] || acInst;
|
q[fk2] = acInst[idName] || acInst;
|
||||||
params.through.findOne({where: q}, function(err, d) {
|
params.through.findOne({where: q}, function (err, d) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
|
@ -185,7 +186,7 @@ Relation.belongsTo = function (anotherClass, params) {
|
||||||
anotherClass = params.model;
|
anotherClass = params.model;
|
||||||
} else {
|
} else {
|
||||||
var anotherClassName = anotherClass.toLowerCase();
|
var anotherClassName = anotherClass.toLowerCase();
|
||||||
for(var name in this.dataSource.modelBuilder.models) {
|
for (var name in this.dataSource.modelBuilder.models) {
|
||||||
if (name.toLowerCase() === anotherClassName) {
|
if (name.toLowerCase() === anotherClassName) {
|
||||||
anotherClass = this.dataSource.modelBuilder.models[name];
|
anotherClass = this.dataSource.modelBuilder.models[name];
|
||||||
}
|
}
|
||||||
|
@ -213,7 +214,7 @@ Relation.belongsTo = function (anotherClass, params) {
|
||||||
cb(null, null);
|
cb(null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
anotherClass.findById(id, function (err,inst) {
|
anotherClass.findById(id, function (err, inst) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (!inst) return cb(null, null);
|
if (!inst) return cb(null, null);
|
||||||
if (inst[idName] === this[fk]) {
|
if (inst[idName] === this[fk]) {
|
||||||
|
@ -241,7 +242,7 @@ Relation.belongsTo = function (anotherClass, params) {
|
||||||
this.__cachedRelations[methodName] = p;
|
this.__cachedRelations[methodName] = p;
|
||||||
} else if (typeof p === 'function') { // acts as async getter
|
} else if (typeof p === 'function') { // acts as async getter
|
||||||
if (typeof cachedValue === 'undefined') {
|
if (typeof cachedValue === 'undefined') {
|
||||||
this.__finders__[methodName].apply(self, [this[fk], function(err, inst) {
|
this.__finders__[methodName].apply(self, [this[fk], function (err, inst) {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
self.__cachedRelations[methodName] = inst;
|
self.__cachedRelations[methodName] = inst;
|
||||||
}
|
}
|
||||||
|
|
20
lib/scope.js
20
lib/scope.js
|
@ -57,7 +57,7 @@ function defineScope(cls, targetClass, name, params, methods) {
|
||||||
if (!this.__cachedRelations || (typeof this.__cachedRelations[name] == 'undefined') || actualRefresh) {
|
if (!this.__cachedRelations || (typeof this.__cachedRelations[name] == 'undefined') || actualRefresh) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var params = mergeParams(actualCond, caller._scope);
|
var params = mergeParams(actualCond, caller._scope);
|
||||||
return targetClass.find(params, function(err, data) {
|
return targetClass.find(params, function (err, data) {
|
||||||
if (!err && saveOnCache) {
|
if (!err && saveOnCache) {
|
||||||
if (!self.__cachedRelations) {
|
if (!self.__cachedRelations) {
|
||||||
self.__cachedRelations = {};
|
self.__cachedRelations = {};
|
||||||
|
@ -94,7 +94,7 @@ function defineScope(cls, targetClass, name, params, methods) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wrap the property into a function for remoting
|
// Wrap the property into a function for remoting
|
||||||
var fn = function() {
|
var fn = function () {
|
||||||
// primaryObject.scopeName, such as user.accounts
|
// primaryObject.scopeName, such as user.accounts
|
||||||
var f = this[name];
|
var f = this[name];
|
||||||
// set receiver to be the scope property whose value is a function
|
// set receiver to be the scope property whose value is a function
|
||||||
|
@ -109,7 +109,7 @@ function defineScope(cls, targetClass, name, params, methods) {
|
||||||
|
|
||||||
cls['__get__' + name] = fn;
|
cls['__get__' + name] = fn;
|
||||||
|
|
||||||
var fn_create = function() {
|
var fn_create = function () {
|
||||||
var f = this[name].create;
|
var f = this[name].create;
|
||||||
f.apply(this[name], arguments);
|
f.apply(this[name], arguments);
|
||||||
};
|
};
|
||||||
|
@ -122,7 +122,7 @@ function defineScope(cls, targetClass, name, params, methods) {
|
||||||
|
|
||||||
cls['__create__' + name] = fn_create;
|
cls['__create__' + name] = fn_create;
|
||||||
|
|
||||||
var fn_delete = function() {
|
var fn_delete = function () {
|
||||||
var f = this[name].destroyAll;
|
var f = this[name].destroyAll;
|
||||||
f.apply(this[name], arguments);
|
f.apply(this[name], arguments);
|
||||||
};
|
};
|
||||||
|
@ -135,7 +135,7 @@ function defineScope(cls, 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) {
|
||||||
return new targetClass(mergeParams(this._scope, {where:data || {}}).where);
|
return new targetClass(mergeParams(this._scope, {where: data || {}}).where);
|
||||||
}
|
}
|
||||||
|
|
||||||
function create(data, cb) {
|
function create(data, cb) {
|
||||||
|
@ -157,14 +157,14 @@ function defineScope(cls, targetClass, name, params, methods) {
|
||||||
if (err) {
|
if (err) {
|
||||||
cb(err);
|
cb(err);
|
||||||
} else {
|
} else {
|
||||||
(function loopOfDestruction (data) {
|
(function loopOfDestruction(data) {
|
||||||
if(data.length > 0) {
|
if (data.length > 0) {
|
||||||
data.shift().destroy(function(err) {
|
data.shift().destroy(function (err) {
|
||||||
if(err && cb) cb(err);
|
if (err && cb) cb(err);
|
||||||
loopOfDestruction(data);
|
loopOfDestruction(data);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if(cb) cb();
|
if (cb) cb();
|
||||||
}
|
}
|
||||||
}(data));
|
}(data));
|
||||||
}
|
}
|
||||||
|
|
15
lib/sql.js
15
lib/sql.js
|
@ -34,7 +34,6 @@ BaseSQL.prototype.queryOne = function (sql, callback) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the table name for a given model
|
* Get the table name for a given model
|
||||||
* @param {String} model The model name
|
* @param {String} model The model name
|
||||||
|
@ -43,7 +42,7 @@ BaseSQL.prototype.queryOne = function (sql, callback) {
|
||||||
BaseSQL.prototype.table = function (model) {
|
BaseSQL.prototype.table = function (model) {
|
||||||
var name = this.getDataSource(model).tableName(model);
|
var name = this.getDataSource(model).tableName(model);
|
||||||
var dbName = this.dbName;
|
var dbName = this.dbName;
|
||||||
if(typeof dbName === 'function') {
|
if (typeof dbName === 'function') {
|
||||||
name = dbName(name);
|
name = dbName(name);
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
|
@ -58,7 +57,7 @@ BaseSQL.prototype.table = function (model) {
|
||||||
BaseSQL.prototype.column = function (model, property) {
|
BaseSQL.prototype.column = function (model, property) {
|
||||||
var name = this.getDataSource(model).columnName(model, property);
|
var name = this.getDataSource(model).columnName(model, property);
|
||||||
var dbName = this.dbName;
|
var dbName = this.dbName;
|
||||||
if(typeof dbName === 'function') {
|
if (typeof dbName === 'function') {
|
||||||
name = dbName(name);
|
name = dbName(name);
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
|
@ -82,8 +81,8 @@ BaseSQL.prototype.columnMetadata = function (model, property) {
|
||||||
*/
|
*/
|
||||||
BaseSQL.prototype.propertyName = function (model, column) {
|
BaseSQL.prototype.propertyName = function (model, column) {
|
||||||
var props = this._models[model].properties;
|
var props = this._models[model].properties;
|
||||||
for(var p in props) {
|
for (var p in props) {
|
||||||
if(this.column(model, p) === column) {
|
if (this.column(model, p) === column) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,9 +95,10 @@ BaseSQL.prototype.propertyName = function (model, column) {
|
||||||
* @returns {String} The column name
|
* @returns {String} The column name
|
||||||
*/
|
*/
|
||||||
BaseSQL.prototype.idColumn = function (model) {
|
BaseSQL.prototype.idColumn = function (model) {
|
||||||
var name = this.getDataSource(model).idColumnName(model);;
|
var name = this.getDataSource(model).idColumnName(model);
|
||||||
|
;
|
||||||
var dbName = this.dbName;
|
var dbName = this.dbName;
|
||||||
if(typeof dbName === 'function') {
|
if (typeof dbName === 'function') {
|
||||||
name = dbName(name);
|
name = dbName(name);
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
|
@ -155,7 +155,6 @@ BaseSQL.prototype.save = function (model, data, callback) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a model instance exists for the given id value
|
* Check if a model instance exists for the given id value
|
||||||
* @param {String} model The model name
|
* @param {String} model The model name
|
||||||
|
|
|
@ -58,4 +58,4 @@ module.exports = function (Types) {
|
||||||
Types.registerType(Array);
|
Types.registerType(Array);
|
||||||
Types.registerType(GeoPoint);
|
Types.registerType(GeoPoint);
|
||||||
Types.registerType(Object);
|
Types.registerType(Object);
|
||||||
}
|
};
|
19
lib/utils.js
19
lib/utils.js
|
@ -11,18 +11,20 @@ function safeRequire(module) {
|
||||||
try {
|
try {
|
||||||
return require(module);
|
return require(module);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('Run "npm install loopback-datasource-juggler ' + module + '" command to use loopback-datasource-juggler using ' + module + ' database engine');
|
console.log('Run "npm install loopback-datasource-juggler ' + module
|
||||||
|
+ '" command to use loopback-datasource-juggler using ' + module
|
||||||
|
+ ' database engine');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fieldsToArray(fields, properties) {
|
function fieldsToArray(fields, properties) {
|
||||||
if(!fields) return;
|
if (!fields) return;
|
||||||
|
|
||||||
// include all properties by default
|
// include all properties by default
|
||||||
var result = properties;
|
var result = properties;
|
||||||
|
|
||||||
if(typeof fields === 'string') {
|
if (typeof fields === 'string') {
|
||||||
return [fields];
|
return [fields];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +38,7 @@ function fieldsToArray(fields, properties) {
|
||||||
var included = [];
|
var included = [];
|
||||||
var excluded = [];
|
var excluded = [];
|
||||||
var keys = Object.keys(fields);
|
var keys = Object.keys(fields);
|
||||||
if(!keys.length) return;
|
if (!keys.length) return;
|
||||||
|
|
||||||
keys.forEach(function (k) {
|
keys.forEach(function (k) {
|
||||||
if (fields[k]) {
|
if (fields[k]) {
|
||||||
|
@ -89,7 +91,8 @@ function removeUndefined(query) {
|
||||||
this.remove();
|
this.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Array.isArray(x) && (typeof x === 'object' && x !== null && x.constructor !== Object)) {
|
if (!Array.isArray(x) && (typeof x === 'object' && x !== null
|
||||||
|
&& x.constructor !== Object)) {
|
||||||
// This object is not a plain object
|
// This object is not a plain object
|
||||||
this.update(x, true); // Stop navigating into this object
|
this.update(x, true); // Stop navigating into this object
|
||||||
return x;
|
return x;
|
||||||
|
@ -108,7 +111,7 @@ var qs = require('qs');
|
||||||
* @returns {Object} The settings object
|
* @returns {Object} The settings object
|
||||||
*/
|
*/
|
||||||
function parseSettings(urlStr) {
|
function parseSettings(urlStr) {
|
||||||
if(!urlStr) {
|
if (!urlStr) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
var uri = url.parse(urlStr, false);
|
var uri = url.parse(urlStr, false);
|
||||||
|
@ -120,9 +123,9 @@ function parseSettings(urlStr) {
|
||||||
settings.password = uri.auth && uri.auth.split(':')[1];
|
settings.password = uri.auth && uri.auth.split(':')[1];
|
||||||
settings.database = uri.pathname && uri.pathname.split('/')[1]; // remove the leading /
|
settings.database = uri.pathname && uri.pathname.split('/')[1]; // remove the leading /
|
||||||
settings.url = urlStr;
|
settings.url = urlStr;
|
||||||
if(uri.query) {
|
if (uri.query) {
|
||||||
var params = qs.parse(uri.query);
|
var params = qs.parse(uri.query);
|
||||||
for(var p in params) {
|
for (var p in params) {
|
||||||
settings[p] = params[p];
|
settings[p] = params[p];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,7 +348,7 @@ Validatable.prototype.isValid = function (callback, data) {
|
||||||
cleanErrors(this);
|
cleanErrors(this);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
this.trigger('validate', function (validationsDone) {
|
this.trigger('validate', function (validationsDone) {
|
||||||
validationsDone.call(inst, function() {
|
validationsDone.call(inst, function () {
|
||||||
callback(valid);
|
callback(valid);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -382,7 +382,7 @@ Validatable.prototype.isValid = function (callback, data) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!async) {
|
if (!async) {
|
||||||
validationsDone.call(inst, function() {
|
validationsDone.call(inst, function () {
|
||||||
if (valid) cleanErrors(inst);
|
if (valid) cleanErrors(inst);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback(valid);
|
callback(valid);
|
||||||
|
@ -590,7 +590,7 @@ Errors.prototype.add = function (field, message, code) {
|
||||||
|
|
||||||
function ErrorCodes(messages) {
|
function ErrorCodes(messages) {
|
||||||
var c = this;
|
var c = this;
|
||||||
Object.keys(messages).forEach(function(field) {
|
Object.keys(messages).forEach(function (field) {
|
||||||
c[field] = messages[field].codes;
|
c[field] = messages[field].codes;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
var should = require('./init.js');
|
var should = require('./init.js');
|
||||||
var db, User;
|
var db, User;
|
||||||
|
|
||||||
describe('basic-querying', function() {
|
describe('basic-querying', function () {
|
||||||
|
|
||||||
before(function(done) {
|
before(function (done) {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
|
|
||||||
User = db.define('User', {
|
User = db.define('User', {
|
||||||
|
@ -18,26 +18,25 @@ describe('basic-querying', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('findById', function () {
|
||||||
|
|
||||||
describe('findById', function() {
|
before(function (done) {
|
||||||
|
|
||||||
before(function(done) {
|
|
||||||
User.destroyAll(done);
|
User.destroyAll(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query by id: not found', function(done) {
|
it('should query by id: not found', function (done) {
|
||||||
User.findById(1, function(err, u) {
|
User.findById(1, function (err, u) {
|
||||||
should.not.exist(u);
|
should.not.exist(u);
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query by id: found', function(done) {
|
it('should query by id: found', function (done) {
|
||||||
User.create(function(err, u) {
|
User.create(function (err, u) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(u.id);
|
should.exist(u.id);
|
||||||
User.findById(u.id, function(err, u) {
|
User.findById(u.id, function (err, u) {
|
||||||
should.exist(u);
|
should.exist(u);
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
u.should.be.an.instanceOf(User);
|
u.should.be.an.instanceOf(User);
|
||||||
|
@ -48,12 +47,12 @@ describe('basic-querying', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('find', function() {
|
describe('find', function () {
|
||||||
|
|
||||||
before(seed);
|
before(seed);
|
||||||
|
|
||||||
it('should query collection', function(done) {
|
it('should query collection', function (done) {
|
||||||
User.find(function(err, users) {
|
User.find(function (err, users) {
|
||||||
should.exists(users);
|
should.exists(users);
|
||||||
should.not.exists(err);
|
should.not.exists(err);
|
||||||
users.should.have.lengthOf(6);
|
users.should.have.lengthOf(6);
|
||||||
|
@ -61,8 +60,8 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query limited collection', function(done) {
|
it('should query limited collection', function (done) {
|
||||||
User.find({limit: 3}, function(err, users) {
|
User.find({limit: 3}, function (err, users) {
|
||||||
should.exists(users);
|
should.exists(users);
|
||||||
should.not.exists(err);
|
should.not.exists(err);
|
||||||
users.should.have.lengthOf(3);
|
users.should.have.lengthOf(3);
|
||||||
|
@ -70,8 +69,8 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query offset collection with limit', function(done) {
|
it('should query offset collection with limit', function (done) {
|
||||||
User.find({skip: 1, limit: 4}, function(err, users) {
|
User.find({skip: 1, limit: 4}, function (err, users) {
|
||||||
should.exists(users);
|
should.exists(users);
|
||||||
should.not.exists(err);
|
should.not.exists(err);
|
||||||
users.should.have.lengthOf(4);
|
users.should.have.lengthOf(4);
|
||||||
|
@ -79,8 +78,8 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query filtered collection', function(done) {
|
it('should query filtered collection', function (done) {
|
||||||
User.find({where: {role: 'lead'}}, function(err, users) {
|
User.find({where: {role: 'lead'}}, function (err, users) {
|
||||||
should.exists(users);
|
should.exists(users);
|
||||||
should.not.exists(err);
|
should.not.exists(err);
|
||||||
users.should.have.lengthOf(2);
|
users.should.have.lengthOf(2);
|
||||||
|
@ -88,30 +87,30 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query collection sorted by numeric field', function(done) {
|
it('should query collection sorted by numeric field', function (done) {
|
||||||
User.find({order: 'order'}, function(err, users) {
|
User.find({order: 'order'}, function (err, users) {
|
||||||
should.exists(users);
|
should.exists(users);
|
||||||
should.not.exists(err);
|
should.not.exists(err);
|
||||||
users.forEach(function(u, i) {
|
users.forEach(function (u, i) {
|
||||||
u.order.should.eql(i + 1);
|
u.order.should.eql(i + 1);
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query collection desc sorted by numeric field', function(done) {
|
it('should query collection desc sorted by numeric field', function (done) {
|
||||||
User.find({order: 'order DESC'}, function(err, users) {
|
User.find({order: 'order DESC'}, function (err, users) {
|
||||||
should.exists(users);
|
should.exists(users);
|
||||||
should.not.exists(err);
|
should.not.exists(err);
|
||||||
users.forEach(function(u, i) {
|
users.forEach(function (u, i) {
|
||||||
u.order.should.eql(users.length - i);
|
u.order.should.eql(users.length - i);
|
||||||
});
|
});
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query collection sorted by string field', function(done) {
|
it('should query collection sorted by string field', function (done) {
|
||||||
User.find({order: 'name'}, function(err, users) {
|
User.find({order: 'name'}, function (err, users) {
|
||||||
should.exists(users);
|
should.exists(users);
|
||||||
should.not.exists(err);
|
should.not.exists(err);
|
||||||
users.shift().name.should.equal('George Harrison');
|
users.shift().name.should.equal('George Harrison');
|
||||||
|
@ -121,8 +120,8 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query collection desc sorted by string field', function(done) {
|
it('should query collection desc sorted by string field', function (done) {
|
||||||
User.find({order: 'name DESC'}, function(err, users) {
|
User.find({order: 'name DESC'}, function (err, users) {
|
||||||
should.exists(users);
|
should.exists(users);
|
||||||
should.not.exists(err);
|
should.not.exists(err);
|
||||||
users.pop().name.should.equal('George Harrison');
|
users.pop().name.should.equal('George Harrison');
|
||||||
|
@ -132,7 +131,7 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should only include fields as specified', function(done) {
|
it('should only include fields as specified', function (done) {
|
||||||
var remaining = 0;
|
var remaining = 0;
|
||||||
|
|
||||||
function sample(fields) {
|
function sample(fields) {
|
||||||
|
@ -140,14 +139,14 @@ describe('basic-querying', function() {
|
||||||
return {
|
return {
|
||||||
expect: function (arr) {
|
expect: function (arr) {
|
||||||
remaining++;
|
remaining++;
|
||||||
User.find({fields: fields}, function(err, users) {
|
User.find({fields: fields}, function (err, users) {
|
||||||
|
|
||||||
remaining--;
|
remaining--;
|
||||||
if(err) return done(err);
|
if (err) return done(err);
|
||||||
|
|
||||||
should.exists(users);
|
should.exists(users);
|
||||||
|
|
||||||
if(remaining === 0) {
|
if (remaining === 0) {
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,11 +156,11 @@ describe('basic-querying', function() {
|
||||||
Object.keys(obj)
|
Object.keys(obj)
|
||||||
.forEach(function (key) {
|
.forEach(function (key) {
|
||||||
// if the obj has an unexpected value
|
// if the obj has an unexpected value
|
||||||
if(obj[key] !== undefined && arr.indexOf(key) === -1) {
|
if (obj[key] !== undefined && arr.indexOf(key) === -1) {
|
||||||
console.log('Given fields:', fields);
|
console.log('Given fields:', fields);
|
||||||
console.log('Got:', key, obj[key]);
|
console.log('Got:', key, obj[key]);
|
||||||
console.log('Expected:', arr);
|
console.log('Expected:', arr);
|
||||||
throw new Error('should not include data for key: '+ key);
|
throw new Error('should not include data for key: ' + key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -181,12 +180,12 @@ describe('basic-querying', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('count', function() {
|
describe('count', function () {
|
||||||
|
|
||||||
before(seed);
|
before(seed);
|
||||||
|
|
||||||
it('should query total count', function(done) {
|
it('should query total count', function (done) {
|
||||||
User.count(function(err, n) {
|
User.count(function (err, n) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(n);
|
should.exist(n);
|
||||||
n.should.equal(6);
|
n.should.equal(6);
|
||||||
|
@ -194,8 +193,8 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query filtered count', function(done) {
|
it('should query filtered count', function (done) {
|
||||||
User.count({role: 'lead'}, function(err, n) {
|
User.count({role: 'lead'}, function (err, n) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(n);
|
should.exist(n);
|
||||||
n.should.equal(2);
|
n.should.equal(2);
|
||||||
|
@ -204,13 +203,13 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('findOne', function() {
|
describe('findOne', function () {
|
||||||
|
|
||||||
before(seed);
|
before(seed);
|
||||||
|
|
||||||
it('should find first record (default sort by id)', function(done) {
|
it('should find first record (default sort by id)', function (done) {
|
||||||
User.all({order: 'id'}, function(err, users) {
|
User.all({order: 'id'}, function (err, users) {
|
||||||
User.findOne(function(e, u) {
|
User.findOne(function (e, u) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(u);
|
should.exist(u);
|
||||||
u.id.toString().should.equal(users[0].id.toString());
|
u.id.toString().should.equal(users[0].id.toString());
|
||||||
|
@ -219,8 +218,8 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find first record', function(done) {
|
it('should find first record', function (done) {
|
||||||
User.findOne({order: 'order'}, function(e, u) {
|
User.findOne({order: 'order'}, function (e, u) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(u);
|
should.exist(u);
|
||||||
u.order.should.equal(1);
|
u.order.should.equal(1);
|
||||||
|
@ -229,8 +228,8 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find last record', function(done) {
|
it('should find last record', function (done) {
|
||||||
User.findOne({order: 'order DESC'}, function(e, u) {
|
User.findOne({order: 'order DESC'}, function (e, u) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(u);
|
should.exist(u);
|
||||||
u.order.should.equal(6);
|
u.order.should.equal(6);
|
||||||
|
@ -239,11 +238,11 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find last record in filtered set', function(done) {
|
it('should find last record in filtered set', function (done) {
|
||||||
User.findOne({
|
User.findOne({
|
||||||
where: {role: 'lead'},
|
where: {role: 'lead'},
|
||||||
order: 'order DESC'
|
order: 'order DESC'
|
||||||
}, function(e, u) {
|
}, function (e, u) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(u);
|
should.exist(u);
|
||||||
u.order.should.equal(2);
|
u.order.should.equal(2);
|
||||||
|
@ -252,9 +251,9 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work even when find by id', function(done) {
|
it('should work even when find by id', function (done) {
|
||||||
User.findOne(function(e, u) {
|
User.findOne(function (e, u) {
|
||||||
User.findOne({where: {id: u.id}}, function(err, user) {
|
User.findOne({where: {id: u.id}}, function (err, user) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(user);
|
should.exist(user);
|
||||||
done();
|
done();
|
||||||
|
@ -264,13 +263,13 @@ describe('basic-querying', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('exists', function() {
|
describe('exists', function () {
|
||||||
|
|
||||||
before(seed);
|
before(seed);
|
||||||
|
|
||||||
it('should check whether record exist', function(done) {
|
it('should check whether record exist', function (done) {
|
||||||
User.findOne(function(e, u) {
|
User.findOne(function (e, u) {
|
||||||
User.exists(u.id, function(err, exists) {
|
User.exists(u.id, function (err, exists) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(exists);
|
should.exist(exists);
|
||||||
exists.should.be.ok;
|
exists.should.be.ok;
|
||||||
|
@ -279,9 +278,9 @@ describe('basic-querying', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check whether record not exist', function(done) {
|
it('should check whether record not exist', function (done) {
|
||||||
User.destroyAll(function() {
|
User.destroyAll(function () {
|
||||||
User.exists(42, function(err, exists) {
|
User.exists(42, function (err, exists) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
exists.should.not.be.ok;
|
exists.should.not.be.ok;
|
||||||
done();
|
done();
|
||||||
|
@ -291,16 +290,16 @@ describe('basic-querying', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('destroyAll with where option', function() {
|
describe('destroyAll with where option', function () {
|
||||||
|
|
||||||
before(seed);
|
before(seed);
|
||||||
|
|
||||||
it('should only delete instances that satisfy the where condition', function(done) {
|
it('should only delete instances that satisfy the where condition', function (done) {
|
||||||
User.destroyAll({name: 'John Lennon'}, function() {
|
User.destroyAll({name: 'John Lennon'}, function () {
|
||||||
User.find({where: {name: 'John Lennon'}}, function(err, data) {
|
User.find({where: {name: 'John Lennon'}}, function (err, data) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
data.length.should.equal(0);
|
data.length.should.equal(0);
|
||||||
User.find({where: {name: 'Paul McCartney'}}, function(err, data) {
|
User.find({where: {name: 'Paul McCartney'}}, function (err, data) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
data.length.should.equal(1);
|
data.length.should.equal(1);
|
||||||
done();
|
done();
|
||||||
|
@ -311,8 +310,6 @@ describe('basic-querying', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function seed(done) {
|
function seed(done) {
|
||||||
|
@ -323,7 +320,8 @@ function seed(done) {
|
||||||
email: 'john@b3atl3s.co.uk',
|
email: 'john@b3atl3s.co.uk',
|
||||||
role: 'lead',
|
role: 'lead',
|
||||||
order: 2
|
order: 2
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
name: 'Paul McCartney',
|
name: 'Paul McCartney',
|
||||||
email: 'paul@b3atl3s.co.uk',
|
email: 'paul@b3atl3s.co.uk',
|
||||||
role: 'lead',
|
role: 'lead',
|
||||||
|
@ -334,8 +332,8 @@ function seed(done) {
|
||||||
{name: 'Pete Best', order: 4},
|
{name: 'Pete Best', order: 4},
|
||||||
{name: 'Stuart Sutcliffe', order: 3}
|
{name: 'Stuart Sutcliffe', order: 3}
|
||||||
];
|
];
|
||||||
User.destroyAll(function() {
|
User.destroyAll(function () {
|
||||||
beatles.forEach(function(beatle) {
|
beatles.forEach(function (beatle) {
|
||||||
User.create(beatle, ok);
|
User.create(beatle, ok);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
var Schema = require('../index').Schema;
|
var Schema = require('../index').Schema;
|
||||||
var Text = Schema.Text;
|
var Text = Schema.Text;
|
||||||
|
|
||||||
|
@ -72,6 +71,7 @@ function clearAndCreate(model, data, callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
var itemIndex = 0;
|
var itemIndex = 0;
|
||||||
|
|
||||||
function nextItem(err, lastItem) {
|
function nextItem(err, lastItem) {
|
||||||
if (lastItem !== null) {
|
if (lastItem !== null) {
|
||||||
createdItems.push(lastItem);
|
createdItems.push(lastItem);
|
||||||
|
@ -103,12 +103,12 @@ function testOrm(dataSource) {
|
||||||
});
|
});
|
||||||
|
|
||||||
Dog = dataSource.define('Dog', {
|
Dog = dataSource.define('Dog', {
|
||||||
name : { type: String, limit: 64, allowNull: false }
|
name: { type: String, limit: 64, allowNull: false }
|
||||||
});
|
});
|
||||||
|
|
||||||
Log = dataSource.define('Log', {
|
Log = dataSource.define('Log', {
|
||||||
ownerId : { type: Number, allowNull: true },
|
ownerId: { type: Number, allowNull: true },
|
||||||
name : { type: String, limit: 64, allowNull: false }
|
name: { type: String, limit: 64, allowNull: false }
|
||||||
});
|
});
|
||||||
|
|
||||||
Log.belongsTo(Dog, {as: 'owner', foreignKey: 'ownerId'});
|
Log.belongsTo(Dog, {as: 'owner', foreignKey: 'ownerId'});
|
||||||
|
@ -125,13 +125,17 @@ function testOrm(dataSource) {
|
||||||
title: { type: String, length: 255, index: true },
|
title: { type: String, length: 255, index: true },
|
||||||
subject: { type: String },
|
subject: { type: String },
|
||||||
content: { type: Text },
|
content: { type: Text },
|
||||||
date: { type: Date, default: function () { return new Date }, index: true },
|
date: { type: Date, default: function () {
|
||||||
|
return new Date
|
||||||
|
}, index: true },
|
||||||
published: { type: Boolean, default: false, index: true },
|
published: { type: Boolean, default: false, index: true },
|
||||||
likes: [],
|
likes: [],
|
||||||
related: [RelatedPost]
|
related: [RelatedPost]
|
||||||
}, {table: 'posts'});
|
}, {table: 'posts'});
|
||||||
|
|
||||||
function RelatedPost() { }
|
function RelatedPost() {
|
||||||
|
}
|
||||||
|
|
||||||
RelatedPost.prototype.someMethod = function () {
|
RelatedPost.prototype.someMethod = function () {
|
||||||
return this.parent;
|
return this.parent;
|
||||||
};
|
};
|
||||||
|
@ -417,7 +421,6 @@ function testOrm(dataSource) {
|
||||||
test.done();
|
test.done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should handle hasMany relationship', function (test) {
|
it('should handle hasMany relationship', function (test) {
|
||||||
User.create(function (err, u) {
|
User.create(function (err, u) {
|
||||||
if (err) return console.log(err);
|
if (err) return console.log(err);
|
||||||
|
@ -434,23 +437,23 @@ function testOrm(dataSource) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should navigate variations of belongsTo regardless of column name', function(test){
|
it('should navigate variations of belongsTo regardless of column name', function (test) {
|
||||||
|
|
||||||
Dog.create({name: 'theDog'}, function(err, obj){
|
Dog.create({name: 'theDog'}, function (err, obj) {
|
||||||
test.ok(obj instanceof Dog);
|
test.ok(obj instanceof Dog);
|
||||||
Log.create({name: 'theLog', ownerId: obj.id}, function(err, obj){
|
Log.create({name: 'theLog', ownerId: obj.id}, function (err, obj) {
|
||||||
test.ok(obj instanceof Log);
|
test.ok(obj instanceof Log);
|
||||||
obj.owner(function(err, obj){
|
obj.owner(function (err, obj) {
|
||||||
test.ok(!err, 'Should not have an error.'); // Before cba174b this would be 'Error: Permission denied'
|
test.ok(!err, 'Should not have an error.'); // Before cba174b this would be 'Error: Permission denied'
|
||||||
if(err){
|
if (err) {
|
||||||
console.log('Found: ' + err);
|
console.log('Found: ' + err);
|
||||||
}
|
}
|
||||||
test.ok(obj, 'Should not find null or undefined.'); // Before cba174b this could be null or undefined.
|
test.ok(obj, 'Should not find null or undefined.'); // Before cba174b this could be null or undefined.
|
||||||
test.ok(obj instanceof Dog, 'Should find a Dog.');
|
test.ok(obj instanceof Dog, 'Should find a Dog.');
|
||||||
if(obj){ // Since test won't stop on fail, have to check before accessing obj.name.
|
if (obj) { // Since test won't stop on fail, have to check before accessing obj.name.
|
||||||
test.ok(obj.name, 'Should have a name.');
|
test.ok(obj.name, 'Should have a name.');
|
||||||
}
|
}
|
||||||
if(obj && obj.name){
|
if (obj && obj.name) {
|
||||||
test.equal(obj.name, 'theDog', 'The owner of theLog is theDog.');
|
test.equal(obj.name, 'theDog', 'The owner of theLog is theDog.');
|
||||||
}
|
}
|
||||||
test.done();
|
test.done();
|
||||||
|
@ -483,15 +486,15 @@ function testOrm(dataSource) {
|
||||||
var post = posts[i];
|
var post = posts[i];
|
||||||
if (post.userId) {
|
if (post.userId) {
|
||||||
// We could get the user with belongs to relationship but it is better if there is no interactions.
|
// We could get the user with belongs to relationship but it is better if there is no interactions.
|
||||||
User.findById(post.userId, function(err, user) {
|
User.findById(post.userId, function (err, user) {
|
||||||
User.create(function(err, voidUser) {
|
User.create(function (err, voidUser) {
|
||||||
Post.create({userId: user.id}, function() {
|
Post.create({userId: user.id}, function () {
|
||||||
|
|
||||||
// There can't be any concurrency because we are counting requests
|
// There can't be any concurrency because we are counting requests
|
||||||
// We are first testing cases when user has posts
|
// We are first testing cases when user has posts
|
||||||
user.posts(function(err, data) {
|
user.posts(function (err, data) {
|
||||||
var nbInitialRequests = nbSchemaRequests;
|
var nbInitialRequests = nbSchemaRequests;
|
||||||
user.posts(function(err, data2) {
|
user.posts(function (err, data2) {
|
||||||
test.equal(data.length, 2, 'There should be 2 posts.');
|
test.equal(data.length, 2, 'There should be 2 posts.');
|
||||||
test.equal(data.length, data2.length, 'Posts should be the same, since we are loading on the same object.');
|
test.equal(data.length, data2.length, 'Posts should be the same, since we are loading on the same object.');
|
||||||
requestsAreCounted && test.equal(nbInitialRequests, nbSchemaRequests, 'There should not be any request because value is cached.');
|
requestsAreCounted && test.equal(nbInitialRequests, nbSchemaRequests, 'There should not be any request because value is cached.');
|
||||||
|
@ -499,23 +502,23 @@ function testOrm(dataSource) {
|
||||||
if (dataSource.name === 'mongodb') { // for the moment mongodb doesn\'t support additional conditions on hasMany relations (see above)
|
if (dataSource.name === 'mongodb') { // for the moment mongodb doesn\'t support additional conditions on hasMany relations (see above)
|
||||||
test.done();
|
test.done();
|
||||||
} else {
|
} else {
|
||||||
user.posts({where: {id: data[0].id}}, function(err, data) {
|
user.posts({where: {id: data[0].id}}, function (err, data) {
|
||||||
test.equal(data.length, 1, 'There should be only one post.');
|
test.equal(data.length, 1, 'There should be only one post.');
|
||||||
requestsAreCounted && test.equal(nbInitialRequests + 1, nbSchemaRequests, 'There should be one additional request since we added conditions.');
|
requestsAreCounted && test.equal(nbInitialRequests + 1, nbSchemaRequests, 'There should be one additional request since we added conditions.');
|
||||||
|
|
||||||
user.posts(function(err, data) {
|
user.posts(function (err, data) {
|
||||||
test.equal(data.length, 2, 'Previous get shouldn\'t have changed cached value though, since there was additional conditions.');
|
test.equal(data.length, 2, 'Previous get shouldn\'t have changed cached value though, since there was additional conditions.');
|
||||||
requestsAreCounted && test.equal(nbInitialRequests + 1, nbSchemaRequests, 'There should not be any request because value is cached.');
|
requestsAreCounted && test.equal(nbInitialRequests + 1, nbSchemaRequests, 'There should not be any request because value is cached.');
|
||||||
|
|
||||||
// We are now testing cases when user doesn't have any post
|
// We are now testing cases when user doesn't have any post
|
||||||
voidUser.posts(function(err, data) {
|
voidUser.posts(function (err, data) {
|
||||||
var nbInitialRequests = nbSchemaRequests;
|
var nbInitialRequests = nbSchemaRequests;
|
||||||
voidUser.posts(function(err, data2) {
|
voidUser.posts(function (err, data2) {
|
||||||
test.equal(data.length, 0, 'There shouldn\'t be any posts (1/2).');
|
test.equal(data.length, 0, 'There shouldn\'t be any posts (1/2).');
|
||||||
test.equal(data2.length, 0, 'There shouldn\'t be any posts (2/2).');
|
test.equal(data2.length, 0, 'There shouldn\'t be any posts (2/2).');
|
||||||
requestsAreCounted && test.equal(nbInitialRequests, nbSchemaRequests, 'There should not be any request because value is cached.');
|
requestsAreCounted && test.equal(nbInitialRequests, nbSchemaRequests, 'There should not be any request because value is cached.');
|
||||||
|
|
||||||
voidUser.posts(true, function(err, data3) {
|
voidUser.posts(true, function (err, data3) {
|
||||||
test.equal(data3.length, 0, 'There shouldn\'t be any posts.');
|
test.equal(data3.length, 0, 'There shouldn\'t be any posts.');
|
||||||
requestsAreCounted && test.equal(nbInitialRequests + 1, nbSchemaRequests, 'There should be one additional request since we forced refresh.');
|
requestsAreCounted && test.equal(nbInitialRequests + 1, nbSchemaRequests, 'There should be one additional request since we forced refresh.');
|
||||||
|
|
||||||
|
@ -588,15 +591,17 @@ function testOrm(dataSource) {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle ORDER clause', function (test) {
|
it('should handle ORDER clause', function (test) {
|
||||||
var titles = [ { title: 'Title A', subject: "B" },
|
var titles = [
|
||||||
|
{ title: 'Title A', subject: "B" },
|
||||||
{ title: 'Title Z', subject: "A" },
|
{ title: 'Title Z', subject: "A" },
|
||||||
{ title: 'Title M', subject: "C" },
|
{ title: 'Title M', subject: "C" },
|
||||||
{ title: 'Title A', subject: "A" },
|
{ title: 'Title A', subject: "A" },
|
||||||
{ title: 'Title B', subject: "A" },
|
{ title: 'Title B', subject: "A" },
|
||||||
{ title: 'Title C', subject: "D" }];
|
{ title: 'Title C', subject: "D" }
|
||||||
|
];
|
||||||
var isRedis = Post.dataSource.name === 'redis';
|
var isRedis = Post.dataSource.name === 'redis';
|
||||||
var dates = isRedis ? [ 5, 9, 0, 17, 10, 9 ] : [
|
var dates = isRedis ? [ 5, 9, 0, 17, 10, 9 ] : [
|
||||||
new Date(1000 * 5 ),
|
new Date(1000 * 5),
|
||||||
new Date(1000 * 9),
|
new Date(1000 * 9),
|
||||||
new Date(1000 * 0),
|
new Date(1000 * 0),
|
||||||
new Date(1000 * 17),
|
new Date(1000 * 17),
|
||||||
|
@ -608,6 +613,7 @@ function testOrm(dataSource) {
|
||||||
});
|
});
|
||||||
|
|
||||||
var i = 0, tests = 0;
|
var i = 0, tests = 0;
|
||||||
|
|
||||||
function done(err, obj) {
|
function done(err, obj) {
|
||||||
if (++i === titles.length) {
|
if (++i === titles.length) {
|
||||||
doFilterAndSortTest();
|
doFilterAndSortTest();
|
||||||
|
@ -686,7 +692,7 @@ function testOrm(dataSource) {
|
||||||
|
|
||||||
function doMultipleSortTest() {
|
function doMultipleSortTest() {
|
||||||
tests += 1;
|
tests += 1;
|
||||||
Post.all({order: "title ASC, subject ASC"}, function(err, posts) {
|
Post.all({order: "title ASC, subject ASC"}, function (err, posts) {
|
||||||
if (err) console.log(err);
|
if (err) console.log(err);
|
||||||
test.equal(posts.length, 6);
|
test.equal(posts.length, 6);
|
||||||
test.equal(posts[0].title, "Title A");
|
test.equal(posts[0].title, "Title A");
|
||||||
|
@ -700,12 +706,12 @@ function testOrm(dataSource) {
|
||||||
|
|
||||||
function doMultipleReverseSortTest() {
|
function doMultipleReverseSortTest() {
|
||||||
tests += 1;
|
tests += 1;
|
||||||
Post.all({order: "title ASC, subject DESC"}, function(err, posts) {
|
Post.all({order: "title ASC, subject DESC"}, function (err, posts) {
|
||||||
if (err) console.log(err);
|
if (err) console.log(err);
|
||||||
test.equal(posts.length, 6);
|
test.equal(posts.length, 6);
|
||||||
test.equal(posts[0].title, "Title A");
|
test.equal(posts[0].title, "Title A");
|
||||||
test.equal(posts[0].subject, "B");
|
test.equal(posts[0].subject, "B");
|
||||||
test.equal(posts[1].title,"Title A");
|
test.equal(posts[1].title, "Title A");
|
||||||
test.equal(posts[1].subject, "A");
|
test.equal(posts[1].subject, "A");
|
||||||
test.equal(posts[5].title, "Title Z");
|
test.equal(posts[5].title, "Title Z");
|
||||||
finished();
|
finished();
|
||||||
|
@ -713,6 +719,7 @@ function testOrm(dataSource) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var fin = 0;
|
var fin = 0;
|
||||||
|
|
||||||
function finished() {
|
function finished() {
|
||||||
if (++fin === tests) {
|
if (++fin === tests) {
|
||||||
test.done();
|
test.done();
|
||||||
|
@ -790,7 +797,6 @@ function testOrm(dataSource) {
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
|
||||||
// if (
|
// if (
|
||||||
// dataSource.name === 'mysql' ||
|
// dataSource.name === 'mysql' ||
|
||||||
// dataSource.name === 'postgres'
|
// dataSource.name === 'postgres'
|
||||||
|
@ -884,6 +890,7 @@ function testOrm(dataSource) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
var tests = 2;
|
var tests = 2;
|
||||||
|
|
||||||
function done() {
|
function done() {
|
||||||
process.nextTick(function () {
|
process.nextTick(function () {
|
||||||
if (--wait === 0) {
|
if (--wait === 0) {
|
||||||
|
|
|
@ -3,9 +3,9 @@ var should = require('./init.js');
|
||||||
|
|
||||||
var db, Model;
|
var db, Model;
|
||||||
|
|
||||||
describe('datatypes', function() {
|
describe('datatypes', function () {
|
||||||
|
|
||||||
before(function(done){
|
before(function (done) {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
Model = db.define('Model', {
|
Model = db.define('Model', {
|
||||||
str: String,
|
str: String,
|
||||||
|
@ -14,17 +14,17 @@ describe('datatypes', function() {
|
||||||
bool: Boolean,
|
bool: Boolean,
|
||||||
list: {type: []},
|
list: {type: []},
|
||||||
});
|
});
|
||||||
db.automigrate(function() {
|
db.automigrate(function () {
|
||||||
Model.destroyAll(done);
|
Model.destroyAll(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should keep types when get read data from db', function(done) {
|
it('should keep types when get read data from db', function (done) {
|
||||||
var d = new Date, id;
|
var d = new Date, id;
|
||||||
|
|
||||||
Model.create({
|
Model.create({
|
||||||
str: 'hello', date: d, num: '3', bool: 1, list: ['test']
|
str: 'hello', date: d, num: '3', bool: 1, list: ['test']
|
||||||
}, function(err, m) {
|
}, function (err, m) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(m && m.id);
|
should.exist(m && m.id);
|
||||||
m.str.should.be.a('string');
|
m.str.should.be.a('string');
|
||||||
|
@ -36,7 +36,7 @@ describe('datatypes', function() {
|
||||||
|
|
||||||
function testFind(next) {
|
function testFind(next) {
|
||||||
debugger;
|
debugger;
|
||||||
Model.findById(id, function(err, m) {
|
Model.findById(id, function (err, m) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(m);
|
should.exist(m);
|
||||||
m.str.should.be.a('string');
|
m.str.should.be.a('string');
|
||||||
|
@ -49,7 +49,7 @@ describe('datatypes', function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function testAll() {
|
function testAll() {
|
||||||
Model.findOne(function(err, m) {
|
Model.findOne(function (err, m) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(m);
|
should.exist(m);
|
||||||
m.str.should.be.a('string');
|
m.str.should.be.a('string');
|
||||||
|
|
|
@ -3,29 +3,29 @@ var should = require('./init.js');
|
||||||
|
|
||||||
var db = getSchema();
|
var db = getSchema();
|
||||||
|
|
||||||
describe('defaults', function() {
|
describe('defaults', function () {
|
||||||
var Server;
|
var Server;
|
||||||
|
|
||||||
before(function() {
|
before(function () {
|
||||||
Server = db.define('Server', {
|
Server = db.define('Server', {
|
||||||
host: String,
|
host: String,
|
||||||
port: {type: Number, default: 80}
|
port: {type: Number, default: 80}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should apply defaults on new', function() {
|
it('should apply defaults on new', function () {
|
||||||
var s = new Server;
|
var s = new Server;
|
||||||
s.port.should.equal(80);
|
s.port.should.equal(80);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should apply defaults on create', function(done) {
|
it('should apply defaults on create', function (done) {
|
||||||
Server.create(function(err, s) {
|
Server.create(function (err, s) {
|
||||||
s.port.should.equal(80);
|
s.port.should.equal(80);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should apply defaults on read', function(done) {
|
it('should apply defaults on read', function (done) {
|
||||||
db.defineProperty('Server', 'host', {
|
db.defineProperty('Server', 'host', {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'localhost'
|
default: 'localhost'
|
||||||
|
|
|
@ -8,9 +8,9 @@ var j = require('../'),
|
||||||
|
|
||||||
db, User;
|
db, User;
|
||||||
|
|
||||||
describe('hooks', function() {
|
describe('hooks', function () {
|
||||||
|
|
||||||
before(function(done) {
|
before(function (done) {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
|
|
||||||
User = db.define('User', {
|
User = db.define('User', {
|
||||||
|
@ -23,27 +23,27 @@ describe('hooks', function() {
|
||||||
db.automigrate(done);
|
db.automigrate(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('initialize', function() {
|
describe('initialize', function () {
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function () {
|
||||||
User.afterInitialize = null;
|
User.afterInitialize = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be triggered on new', function(done) {
|
it('should be triggered on new', function (done) {
|
||||||
User.afterInitialize = function() {
|
User.afterInitialize = function () {
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
new User;
|
new User;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be triggered on create', function(done) {
|
it('should be triggered on create', function (done) {
|
||||||
var user;
|
var user;
|
||||||
User.afterInitialize = function() {
|
User.afterInitialize = function () {
|
||||||
if (this.name === 'Nickolay') {
|
if (this.name === 'Nickolay') {
|
||||||
this.name += ' Rozental';
|
this.name += ' Rozental';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
User.create({name: 'Nickolay'}, function(err, u) {
|
User.create({name: 'Nickolay'}, function (err, u) {
|
||||||
u.id.should.be.ok;
|
u.id.should.be.ok;
|
||||||
u.name.should.equal('Nickolay Rozental');
|
u.name.should.equal('Nickolay Rozental');
|
||||||
done();
|
done();
|
||||||
|
@ -52,35 +52,35 @@ describe('hooks', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('create', function() {
|
describe('create', function () {
|
||||||
|
|
||||||
afterEach(removeHooks('Create'));
|
afterEach(removeHooks('Create'));
|
||||||
|
|
||||||
it('should be triggered on create', function(done) {
|
it('should be triggered on create', function (done) {
|
||||||
addHooks('Create', done);
|
addHooks('Create', done);
|
||||||
User.create();
|
User.create();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be triggered on new', function() {
|
it('should not be triggered on new', function () {
|
||||||
User.beforeCreate = function(next) {
|
User.beforeCreate = function (next) {
|
||||||
should.fail('This should not be called');
|
should.fail('This should not be called');
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
var u = new User;
|
var u = new User;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be triggered on new+save', function(done) {
|
it('should be triggered on new+save', function (done) {
|
||||||
addHooks('Create', done);
|
addHooks('Create', done);
|
||||||
(new User).save();
|
(new User).save();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('afterCreate should not be triggered on failed create', function(done) {
|
it('afterCreate should not be triggered on failed create', function (done) {
|
||||||
var old = User.dataSource.connector.create;
|
var old = User.dataSource.connector.create;
|
||||||
User.dataSource.connector.create = function(modelName, id, cb) {
|
User.dataSource.connector.create = function (modelName, id, cb) {
|
||||||
cb(new Error('error'));
|
cb(new Error('error'));
|
||||||
}
|
}
|
||||||
|
|
||||||
User.afterCreate = function() {
|
User.afterCreate = function () {
|
||||||
throw new Error('shouldn\'t be called')
|
throw new Error('shouldn\'t be called')
|
||||||
};
|
};
|
||||||
User.create(function (err, user) {
|
User.create(function (err, user) {
|
||||||
|
@ -90,37 +90,37 @@ describe('hooks', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('save', function() {
|
describe('save', function () {
|
||||||
afterEach(removeHooks('Save'));
|
afterEach(removeHooks('Save'));
|
||||||
|
|
||||||
it('should be triggered on create', function(done) {
|
it('should be triggered on create', function (done) {
|
||||||
addHooks('Save', done);
|
addHooks('Save', done);
|
||||||
User.create();
|
User.create();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be triggered on new+save', function(done) {
|
it('should be triggered on new+save', function (done) {
|
||||||
addHooks('Save', done);
|
addHooks('Save', done);
|
||||||
(new User).save();
|
(new User).save();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be triggered on updateAttributes', function(done) {
|
it('should be triggered on updateAttributes', function (done) {
|
||||||
User.create(function(err, user) {
|
User.create(function (err, user) {
|
||||||
addHooks('Save', done);
|
addHooks('Save', done);
|
||||||
user.updateAttributes({name: 'Anatoliy'});
|
user.updateAttributes({name: 'Anatoliy'});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be triggered on save', function(done) {
|
it('should be triggered on save', function (done) {
|
||||||
User.create(function(err, user) {
|
User.create(function (err, user) {
|
||||||
addHooks('Save', done);
|
addHooks('Save', done);
|
||||||
user.name = 'Hamburger';
|
user.name = 'Hamburger';
|
||||||
user.save();
|
user.save();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save full object', function(done) {
|
it('should save full object', function (done) {
|
||||||
User.create(function(err, user) {
|
User.create(function (err, user) {
|
||||||
User.beforeSave = function(next, data) {
|
User.beforeSave = function (next, data) {
|
||||||
data.should.have.keys('id', 'name', 'email',
|
data.should.have.keys('id', 'name', 'email',
|
||||||
'password', 'state')
|
'password', 'state')
|
||||||
done();
|
done();
|
||||||
|
@ -129,19 +129,19 @@ describe('hooks', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save actual modifications to database', function(done) {
|
it('should save actual modifications to database', function (done) {
|
||||||
User.beforeSave = function(next, data) {
|
User.beforeSave = function (next, data) {
|
||||||
data.password = 'hash';
|
data.password = 'hash';
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
User.destroyAll(function() {
|
User.destroyAll(function () {
|
||||||
User.create({
|
User.create({
|
||||||
email: 'james.bond@example.com',
|
email: 'james.bond@example.com',
|
||||||
password: '53cr3t'
|
password: '53cr3t'
|
||||||
}, function() {
|
}, function () {
|
||||||
User.findOne({
|
User.findOne({
|
||||||
where: {email: 'james.bond@example.com'}
|
where: {email: 'james.bond@example.com'}
|
||||||
}, function(err, jb) {
|
}, function (err, jb) {
|
||||||
jb.password.should.equal('hash');
|
jb.password.should.equal('hash');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -149,22 +149,22 @@ describe('hooks', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save actual modifications on updateAttributes', function(done) {
|
it('should save actual modifications on updateAttributes', function (done) {
|
||||||
User.beforeSave = function(next, data) {
|
User.beforeSave = function (next, data) {
|
||||||
data.password = 'hash';
|
data.password = 'hash';
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
User.destroyAll(function() {
|
User.destroyAll(function () {
|
||||||
User.create({
|
User.create({
|
||||||
email: 'james.bond@example.com'
|
email: 'james.bond@example.com'
|
||||||
}, function(err, u) {
|
}, function (err, u) {
|
||||||
u.updateAttribute('password', 'new password', function(e, u) {
|
u.updateAttribute('password', 'new password', function (e, u) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(u);
|
should.exist(u);
|
||||||
u.password.should.equal('hash');
|
u.password.should.equal('hash');
|
||||||
User.findOne({
|
User.findOne({
|
||||||
where: {email: 'james.bond@example.com'}
|
where: {email: 'james.bond@example.com'}
|
||||||
}, function(err, jb) {
|
}, function (err, jb) {
|
||||||
jb.password.should.equal('hash');
|
jb.password.should.equal('hash');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -175,33 +175,33 @@ describe('hooks', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('update', function() {
|
describe('update', function () {
|
||||||
afterEach(removeHooks('Update'));
|
afterEach(removeHooks('Update'));
|
||||||
|
|
||||||
it('should not be triggered on create', function() {
|
it('should not be triggered on create', function () {
|
||||||
User.beforeUpdate = function(next) {
|
User.beforeUpdate = function (next) {
|
||||||
should.fail('This should not be called');
|
should.fail('This should not be called');
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
User.create();
|
User.create();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not be triggered on new+save', function() {
|
it('should not be triggered on new+save', function () {
|
||||||
User.beforeUpdate = function(next) {
|
User.beforeUpdate = function (next) {
|
||||||
should.fail('This should not be called');
|
should.fail('This should not be called');
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
(new User).save();
|
(new User).save();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be triggered on updateAttributes', function(done) {
|
it('should be triggered on updateAttributes', function (done) {
|
||||||
User.create(function (err, user) {
|
User.create(function (err, user) {
|
||||||
addHooks('Update', done);
|
addHooks('Update', done);
|
||||||
user.updateAttributes({name: 'Anatoliy'});
|
user.updateAttributes({name: 'Anatoliy'});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be triggered on save', function(done) {
|
it('should be triggered on save', function (done) {
|
||||||
User.create(function (err, user) {
|
User.create(function (err, user) {
|
||||||
addHooks('Update', done);
|
addHooks('Update', done);
|
||||||
user.name = 'Hamburger';
|
user.name = 'Hamburger';
|
||||||
|
@ -209,9 +209,9 @@ describe('hooks', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update limited set of fields', function(done) {
|
it('should update limited set of fields', function (done) {
|
||||||
User.create(function (err, user) {
|
User.create(function (err, user) {
|
||||||
User.beforeUpdate = function(next, data) {
|
User.beforeUpdate = function (next, data) {
|
||||||
data.should.have.keys('name', 'email');
|
data.should.have.keys('name', 'email');
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
|
@ -219,35 +219,35 @@ describe('hooks', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not trigger after-hook on failed save', function(done) {
|
it('should not trigger after-hook on failed save', function (done) {
|
||||||
User.afterUpdate = function() {
|
User.afterUpdate = function () {
|
||||||
should.fail('afterUpdate shouldn\'t be called')
|
should.fail('afterUpdate shouldn\'t be called')
|
||||||
};
|
};
|
||||||
User.create(function (err, user) {
|
User.create(function (err, user) {
|
||||||
var save = User.dataSource.connector.save;
|
var save = User.dataSource.connector.save;
|
||||||
User.dataSource.connector.save = function(modelName, id, cb) {
|
User.dataSource.connector.save = function (modelName, id, cb) {
|
||||||
User.dataSource.connector.save = save;
|
User.dataSource.connector.save = save;
|
||||||
cb(new Error('Error'));
|
cb(new Error('Error'));
|
||||||
}
|
}
|
||||||
|
|
||||||
user.save(function(err) {
|
user.save(function (err) {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('destroy', function() {
|
describe('destroy', function () {
|
||||||
|
|
||||||
afterEach(removeHooks('Destroy'));
|
afterEach(removeHooks('Destroy'));
|
||||||
|
|
||||||
it('should be triggered on destroy', function(done) {
|
it('should be triggered on destroy', function (done) {
|
||||||
var hook = 'not called';
|
var hook = 'not called';
|
||||||
User.beforeDestroy = function(next) {
|
User.beforeDestroy = function (next) {
|
||||||
hook = 'called';
|
hook = 'called';
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
User.afterDestroy = function(next) {
|
User.afterDestroy = function (next) {
|
||||||
hook.should.eql('called');
|
hook.should.eql('called');
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
|
@ -256,16 +256,16 @@ describe('hooks', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not trigger after-hook on failed destroy', function(done) {
|
it('should not trigger after-hook on failed destroy', function (done) {
|
||||||
var destroy = User.dataSource.connector.destroy;
|
var destroy = User.dataSource.connector.destroy;
|
||||||
User.dataSource.connector.destroy = function(modelName, id, cb) {
|
User.dataSource.connector.destroy = function (modelName, id, cb) {
|
||||||
cb(new Error('error'));
|
cb(new Error('error'));
|
||||||
}
|
}
|
||||||
User.afterDestroy = function() {
|
User.afterDestroy = function () {
|
||||||
should.fail('afterDestroy shouldn\'t be called')
|
should.fail('afterDestroy shouldn\'t be called')
|
||||||
};
|
};
|
||||||
User.create(function (err, user) {
|
User.create(function (err, user) {
|
||||||
user.destroy(function(err) {
|
user.destroy(function (err) {
|
||||||
User.dataSource.connector.destroy = destroy;
|
User.dataSource.connector.destroy = destroy;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -274,32 +274,64 @@ describe('hooks', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('lifecycle', function() {
|
describe('lifecycle', function () {
|
||||||
var life = [], user;
|
var life = [], user;
|
||||||
before(function(done) {
|
before(function (done) {
|
||||||
User.beforeSave = function(d){life.push('beforeSave'); d();};
|
User.beforeSave = function (d) {
|
||||||
User.beforeCreate = function(d){life.push('beforeCreate'); d();};
|
life.push('beforeSave');
|
||||||
User.beforeUpdate = function(d){life.push('beforeUpdate'); d();};
|
d();
|
||||||
User.beforeDestroy = function(d){life.push('beforeDestroy');d();};
|
};
|
||||||
User.beforeValidate = function(d){life.push('beforeValidate');d();};
|
User.beforeCreate = function (d) {
|
||||||
User.afterInitialize= function( ){life.push('afterInitialize'); };
|
life.push('beforeCreate');
|
||||||
User.afterSave = function(d){life.push('afterSave'); d();};
|
d();
|
||||||
User.afterCreate = function(d){life.push('afterCreate'); d();};
|
};
|
||||||
User.afterUpdate = function(d){life.push('afterUpdate'); d();};
|
User.beforeUpdate = function (d) {
|
||||||
User.afterDestroy = function(d){life.push('afterDestroy'); d();};
|
life.push('beforeUpdate');
|
||||||
User.afterValidate = function(d){life.push('afterValidate');d();};
|
d();
|
||||||
User.create(function(e, u) {
|
};
|
||||||
|
User.beforeDestroy = function (d) {
|
||||||
|
life.push('beforeDestroy');
|
||||||
|
d();
|
||||||
|
};
|
||||||
|
User.beforeValidate = function (d) {
|
||||||
|
life.push('beforeValidate');
|
||||||
|
d();
|
||||||
|
};
|
||||||
|
User.afterInitialize = function () {
|
||||||
|
life.push('afterInitialize');
|
||||||
|
};
|
||||||
|
User.afterSave = function (d) {
|
||||||
|
life.push('afterSave');
|
||||||
|
d();
|
||||||
|
};
|
||||||
|
User.afterCreate = function (d) {
|
||||||
|
life.push('afterCreate');
|
||||||
|
d();
|
||||||
|
};
|
||||||
|
User.afterUpdate = function (d) {
|
||||||
|
life.push('afterUpdate');
|
||||||
|
d();
|
||||||
|
};
|
||||||
|
User.afterDestroy = function (d) {
|
||||||
|
life.push('afterDestroy');
|
||||||
|
d();
|
||||||
|
};
|
||||||
|
User.afterValidate = function (d) {
|
||||||
|
life.push('afterValidate');
|
||||||
|
d();
|
||||||
|
};
|
||||||
|
User.create(function (e, u) {
|
||||||
user = u;
|
user = u;
|
||||||
life = [];
|
life = [];
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
life = [];
|
life = [];
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should describe create sequence', function(done) {
|
it('should describe create sequence', function (done) {
|
||||||
User.create(function() {
|
User.create(function () {
|
||||||
life.should.eql([
|
life.should.eql([
|
||||||
'afterInitialize',
|
'afterInitialize',
|
||||||
'beforeValidate',
|
'beforeValidate',
|
||||||
|
@ -313,9 +345,9 @@ describe('hooks', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should describe new+save sequence', function(done) {
|
it('should describe new+save sequence', function (done) {
|
||||||
var u = new User;
|
var u = new User;
|
||||||
u.save(function() {
|
u.save(function () {
|
||||||
life.should.eql([
|
life.should.eql([
|
||||||
'afterInitialize',
|
'afterInitialize',
|
||||||
'beforeValidate',
|
'beforeValidate',
|
||||||
|
@ -329,8 +361,8 @@ describe('hooks', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should describe updateAttributes sequence', function(done) {
|
it('should describe updateAttributes sequence', function (done) {
|
||||||
user.updateAttributes({name: 'Antony'}, function() {
|
user.updateAttributes({name: 'Antony'}, function () {
|
||||||
life.should.eql([
|
life.should.eql([
|
||||||
'beforeValidate',
|
'beforeValidate',
|
||||||
'afterValidate',
|
'afterValidate',
|
||||||
|
@ -343,11 +375,11 @@ describe('hooks', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should describe isValid sequence', function(done) {
|
it('should describe isValid sequence', function (done) {
|
||||||
should.not.exist(
|
should.not.exist(
|
||||||
user.constructor._validations,
|
user.constructor._validations,
|
||||||
'Expected user to have no validations, but she have');
|
'Expected user to have no validations, but she have');
|
||||||
user.isValid(function(valid) {
|
user.isValid(function (valid) {
|
||||||
valid.should.be.true;
|
valid.should.be.true;
|
||||||
life.should.eql([
|
life.should.eql([
|
||||||
'beforeValidate',
|
'beforeValidate',
|
||||||
|
@ -357,8 +389,8 @@ describe('hooks', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should describe destroy sequence', function(done) {
|
it('should describe destroy sequence', function (done) {
|
||||||
user.destroy(function() {
|
user.destroy(function () {
|
||||||
life.should.eql([
|
life.should.eql([
|
||||||
'beforeDestroy',
|
'beforeDestroy',
|
||||||
'afterDestroy'
|
'afterDestroy'
|
||||||
|
@ -372,12 +404,12 @@ describe('hooks', function() {
|
||||||
|
|
||||||
function addHooks(name, done) {
|
function addHooks(name, done) {
|
||||||
var called = false, random = String(Math.floor(Math.random() * 1000));
|
var called = false, random = String(Math.floor(Math.random() * 1000));
|
||||||
User['before' + name] = function(next, data) {
|
User['before' + name] = function (next, data) {
|
||||||
called = true;
|
called = true;
|
||||||
data.email = random;
|
data.email = random;
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
User['after' + name] = function(next) {
|
User['after' + name] = function (next) {
|
||||||
(new Boolean(called)).should.equal(true);
|
(new Boolean(called)).should.equal(true);
|
||||||
this.email.should.equal(random);
|
this.email.should.equal(random);
|
||||||
done();
|
done();
|
||||||
|
@ -385,7 +417,7 @@ function addHooks(name, done) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeHooks(name) {
|
function removeHooks(name) {
|
||||||
return function() {
|
return function () {
|
||||||
User['after' + name] = null;
|
User['after' + name] = null;
|
||||||
User['before' + name] = null;
|
User['before' + name] = null;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,14 +4,14 @@ var should = require('./init.js');
|
||||||
var db, User, Post, Passport, City, Street, Building;
|
var db, User, Post, Passport, City, Street, Building;
|
||||||
var nbSchemaRequests = 0;
|
var nbSchemaRequests = 0;
|
||||||
|
|
||||||
describe('include', function() {
|
describe('include', function () {
|
||||||
|
|
||||||
before(setup);
|
before(setup);
|
||||||
|
|
||||||
it('should fetch belongsTo relation', function(done) {
|
it('should fetch belongsTo relation', function (done) {
|
||||||
Passport.all({include: 'owner'}, function (err, passports) {
|
Passport.all({include: 'owner'}, function (err, passports) {
|
||||||
passports.length.should.be.ok;
|
passports.length.should.be.ok;
|
||||||
passports.forEach(function(p) {
|
passports.forEach(function (p) {
|
||||||
p.__cachedRelations.should.have.property('owner');
|
p.__cachedRelations.should.have.property('owner');
|
||||||
var owner = p.__cachedRelations.owner;
|
var owner = p.__cachedRelations.owner;
|
||||||
if (!p.ownerId) {
|
if (!p.ownerId) {
|
||||||
|
@ -25,14 +25,14 @@ describe('include', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch hasMany relation', function(done) {
|
it('should fetch hasMany relation', function (done) {
|
||||||
User.all({include: 'posts'}, function (err, users) {
|
User.all({include: 'posts'}, function (err, users) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(users);
|
should.exist(users);
|
||||||
users.length.should.be.ok;
|
users.length.should.be.ok;
|
||||||
users.forEach(function(u) {
|
users.forEach(function (u) {
|
||||||
u.__cachedRelations.should.have.property('posts');
|
u.__cachedRelations.should.have.property('posts');
|
||||||
u.__cachedRelations.posts.forEach(function(p) {
|
u.__cachedRelations.posts.forEach(function (p) {
|
||||||
p.userId.should.equal(u.id);
|
p.userId.should.equal(u.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -40,12 +40,12 @@ describe('include', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch Passport - Owner - Posts', function(done) {
|
it('should fetch Passport - Owner - Posts', function (done) {
|
||||||
Passport.all({include: {owner: 'posts'}}, function(err, passports) {
|
Passport.all({include: {owner: 'posts'}}, function (err, passports) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(passports);
|
should.exist(passports);
|
||||||
passports.length.should.be.ok;
|
passports.length.should.be.ok;
|
||||||
passports.forEach(function(p) {
|
passports.forEach(function (p) {
|
||||||
p.__cachedRelations.should.have.property('owner');
|
p.__cachedRelations.should.have.property('owner');
|
||||||
var user = p.__cachedRelations.owner;
|
var user = p.__cachedRelations.owner;
|
||||||
if (!p.ownerId) {
|
if (!p.ownerId) {
|
||||||
|
@ -54,7 +54,7 @@ describe('include', function() {
|
||||||
should.exist(user);
|
should.exist(user);
|
||||||
user.id.should.equal(p.ownerId);
|
user.id.should.equal(p.ownerId);
|
||||||
user.__cachedRelations.should.have.property('posts');
|
user.__cachedRelations.should.have.property('posts');
|
||||||
user.__cachedRelations.posts.forEach(function(pp) {
|
user.__cachedRelations.posts.forEach(function (pp) {
|
||||||
pp.userId.should.equal(user.id);
|
pp.userId.should.equal(user.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -63,14 +63,14 @@ describe('include', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch Passports - User - Posts - User', function(done) {
|
it('should fetch Passports - User - Posts - User', function (done) {
|
||||||
Passport.all({
|
Passport.all({
|
||||||
include: {owner: {posts: 'author'}}
|
include: {owner: {posts: 'author'}}
|
||||||
}, function(err, passports) {
|
}, function (err, passports) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(passports);
|
should.exist(passports);
|
||||||
passports.length.should.be.ok;
|
passports.length.should.be.ok;
|
||||||
passports.forEach(function(p) {
|
passports.forEach(function (p) {
|
||||||
p.__cachedRelations.should.have.property('owner');
|
p.__cachedRelations.should.have.property('owner');
|
||||||
var user = p.__cachedRelations.owner;
|
var user = p.__cachedRelations.owner;
|
||||||
if (!p.ownerId) {
|
if (!p.ownerId) {
|
||||||
|
@ -79,7 +79,7 @@ describe('include', function() {
|
||||||
should.exist(user);
|
should.exist(user);
|
||||||
user.id.should.equal(p.ownerId);
|
user.id.should.equal(p.ownerId);
|
||||||
user.__cachedRelations.should.have.property('posts');
|
user.__cachedRelations.should.have.property('posts');
|
||||||
user.__cachedRelations.posts.forEach(function(pp) {
|
user.__cachedRelations.posts.forEach(function (pp) {
|
||||||
pp.userId.should.equal(user.id);
|
pp.userId.should.equal(user.id);
|
||||||
pp.__cachedRelations.should.have.property('author');
|
pp.__cachedRelations.should.have.property('author');
|
||||||
var author = pp.__cachedRelations.author;
|
var author = pp.__cachedRelations.author;
|
||||||
|
@ -91,18 +91,18 @@ describe('include', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch User - Posts AND Passports', function(done) {
|
it('should fetch User - Posts AND Passports', function (done) {
|
||||||
User.all({include: ['posts', 'passports']}, function(err, users) {
|
User.all({include: ['posts', 'passports']}, function (err, users) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(users);
|
should.exist(users);
|
||||||
users.length.should.be.ok;
|
users.length.should.be.ok;
|
||||||
users.forEach(function(user) {
|
users.forEach(function (user) {
|
||||||
user.__cachedRelations.should.have.property('posts');
|
user.__cachedRelations.should.have.property('posts');
|
||||||
user.__cachedRelations.should.have.property('passports');
|
user.__cachedRelations.should.have.property('passports');
|
||||||
user.__cachedRelations.posts.forEach(function(p) {
|
user.__cachedRelations.posts.forEach(function (p) {
|
||||||
p.userId.should.equal(user.id);
|
p.userId.should.equal(user.id);
|
||||||
});
|
});
|
||||||
user.__cachedRelations.passports.forEach(function(pp) {
|
user.__cachedRelations.passports.forEach(function (pp) {
|
||||||
pp.ownerId.should.equal(user.id);
|
pp.ownerId.should.equal(user.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -133,7 +133,7 @@ function setup(done) {
|
||||||
User.hasMany('posts', {foreignKey: 'userId'});
|
User.hasMany('posts', {foreignKey: 'userId'});
|
||||||
Post.belongsTo('author', {model: User, foreignKey: 'userId'});
|
Post.belongsTo('author', {model: User, foreignKey: 'userId'});
|
||||||
|
|
||||||
db.automigrate(function() {
|
db.automigrate(function () {
|
||||||
var createdUsers = [];
|
var createdUsers = [];
|
||||||
var createdPassports = [];
|
var createdPassports = [];
|
||||||
var createdPosts = [];
|
var createdPosts = [];
|
||||||
|
@ -148,7 +148,7 @@ function setup(done) {
|
||||||
{name: 'User D', age: 24},
|
{name: 'User D', age: 24},
|
||||||
{name: 'User E', age: 25}
|
{name: 'User E', age: 25}
|
||||||
],
|
],
|
||||||
function(items) {
|
function (items) {
|
||||||
createdUsers = items;
|
createdUsers = items;
|
||||||
createPassports();
|
createPassports();
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ function setup(done) {
|
||||||
{number: '2', ownerId: createdUsers[1].id},
|
{number: '2', ownerId: createdUsers[1].id},
|
||||||
{number: '3'}
|
{number: '3'}
|
||||||
],
|
],
|
||||||
function(items) {
|
function (items) {
|
||||||
createdPassports = items;
|
createdPassports = items;
|
||||||
createPosts();
|
createPosts();
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ function setup(done) {
|
||||||
{title: 'Post D', userId: createdUsers[1].id},
|
{title: 'Post D', userId: createdUsers[1].id},
|
||||||
{title: 'Post E'}
|
{title: 'Post E'}
|
||||||
],
|
],
|
||||||
function(items) {
|
function (items) {
|
||||||
createdPosts = items;
|
createdPosts = items;
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
@ -197,6 +197,7 @@ function clearAndCreate(model, data, callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
var itemIndex = 0;
|
var itemIndex = 0;
|
||||||
|
|
||||||
function nextItem(err, lastItem) {
|
function nextItem(err, lastItem) {
|
||||||
if (lastItem !== null) {
|
if (lastItem !== null) {
|
||||||
createdItems.push(lastItem);
|
createdItems.push(lastItem);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module.exports = require('should');
|
module.exports = require('should');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (!process.env.TRAVIS) {
|
if (!process.env.TRAVIS) {
|
||||||
if (typeof __cov === 'undefined') {
|
if (typeof __cov === 'undefined') {
|
||||||
process.on('exit', function () {
|
process.on('exit', function () {
|
||||||
require('semicov').report();
|
require('semicov').report();
|
||||||
|
@ -9,13 +9,13 @@ if (!process.env.TRAVIS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
require('semicov').init('lib');
|
require('semicov').init('lib');
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Schema = require('../').Schema;
|
var Schema = require('../').Schema;
|
||||||
|
|
||||||
if (!('getSchema' in global)) {
|
if (!('getSchema' in global)) {
|
||||||
global.getSchema = function() {
|
global.getSchema = function () {
|
||||||
return new Schema('memory');
|
return new Schema('memory');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@ var ModelBuilder = require('../lib/model-builder').ModelBuilder;
|
||||||
var introspectType = require('../lib/introspection')(ModelBuilder);
|
var introspectType = require('../lib/introspection')(ModelBuilder);
|
||||||
var traverse = require('traverse');
|
var traverse = require('traverse');
|
||||||
|
|
||||||
describe('Introspection of model definitions from JSON', function() {
|
describe('Introspection of model definitions from JSON', function () {
|
||||||
|
|
||||||
it('should handle simple types', function() {
|
it('should handle simple types', function () {
|
||||||
assert.equal(introspectType('123'), 'string');
|
assert.equal(introspectType('123'), 'string');
|
||||||
assert.equal(introspectType(true), 'boolean');
|
assert.equal(introspectType(true), 'boolean');
|
||||||
assert.equal(introspectType(false), 'boolean');
|
assert.equal(introspectType(false), 'boolean');
|
||||||
|
@ -13,7 +13,7 @@ describe('Introspection of model definitions from JSON', function() {
|
||||||
assert.equal(introspectType(new Date()), 'date');
|
assert.equal(introspectType(new Date()), 'date');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle array types', function() {
|
it('should handle array types', function () {
|
||||||
var type = introspectType(['123']);
|
var type = introspectType(['123']);
|
||||||
assert.deepEqual(type, ['string'], 'type should be ["string"]');
|
assert.deepEqual(type, ['string'], 'type should be ["string"]');
|
||||||
type = introspectType([1]);
|
type = introspectType([1]);
|
||||||
|
@ -28,12 +28,12 @@ describe('Introspection of model definitions from JSON', function() {
|
||||||
assert.equal(type, 'array');
|
assert.equal(type, 'array');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return Any for null or undefined', function() {
|
it('should return Any for null or undefined', function () {
|
||||||
assert.equal(introspectType(null), ModelBuilder.Any);
|
assert.equal(introspectType(null), ModelBuilder.Any);
|
||||||
assert.equal(introspectType(undefined), ModelBuilder.Any);
|
assert.equal(introspectType(undefined), ModelBuilder.Any);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a schema for object', function() {
|
it('should return a schema for object', function () {
|
||||||
var json = {a: 'str', b: 0, c: true};
|
var json = {a: 'str', b: 0, c: true};
|
||||||
var type = introspectType(json);
|
var type = introspectType(json);
|
||||||
assert.equal(type.a, 'string');
|
assert.equal(type.a, 'string');
|
||||||
|
@ -41,7 +41,7 @@ describe('Introspection of model definitions from JSON', function() {
|
||||||
assert.equal(type.c, 'boolean');
|
assert.equal(type.c, 'boolean');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle nesting objects', function() {
|
it('should handle nesting objects', function () {
|
||||||
var json = {a: 'str', b: 0, c: true, d: {x: 10, y: 5}};
|
var json = {a: 'str', b: 0, c: true, d: {x: 10, y: 5}};
|
||||||
var type = introspectType(json);
|
var type = introspectType(json);
|
||||||
assert.equal(type.a, 'string');
|
assert.equal(type.a, 'string');
|
||||||
|
@ -51,7 +51,7 @@ describe('Introspection of model definitions from JSON', function() {
|
||||||
assert.equal(type.d.y, 'number');
|
assert.equal(type.d.y, 'number');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle nesting arrays', function() {
|
it('should handle nesting arrays', function () {
|
||||||
var json = {a: 'str', b: 0, c: true, d: [1, 2]};
|
var json = {a: 'str', b: 0, c: true, d: [1, 2]};
|
||||||
var type = introspectType(json);
|
var type = introspectType(json);
|
||||||
assert.equal(type.a, 'string');
|
assert.equal(type.a, 'string');
|
||||||
|
@ -60,7 +60,7 @@ describe('Introspection of model definitions from JSON', function() {
|
||||||
assert.deepEqual(type.d, ['number']);
|
assert.deepEqual(type.d, ['number']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should build a model from the introspected schema', function(done) {
|
it('should build a model from the introspected schema', function (done) {
|
||||||
|
|
||||||
var json = {
|
var json = {
|
||||||
name: 'Joe',
|
name: 'Joe',
|
||||||
|
|
|
@ -4,10 +4,10 @@ var should = require('./init.js');
|
||||||
var Schema = require('../').Schema;
|
var Schema = require('../').Schema;
|
||||||
var ModelBuilder = require('../').ModelBuilder;
|
var ModelBuilder = require('../').ModelBuilder;
|
||||||
|
|
||||||
describe('JSON property', function() {
|
describe('JSON property', function () {
|
||||||
var dataSource, Model;
|
var dataSource, Model;
|
||||||
|
|
||||||
it('should be defined', function() {
|
it('should be defined', function () {
|
||||||
dataSource = getSchema();
|
dataSource = getSchema();
|
||||||
Model = dataSource.define('Model', {propertyName: ModelBuilder.JSON});
|
Model = dataSource.define('Model', {propertyName: ModelBuilder.JSON});
|
||||||
var m = new Model;
|
var m = new Model;
|
||||||
|
@ -15,7 +15,7 @@ describe('JSON property', function() {
|
||||||
should.not.exist(m.propertyName);
|
should.not.exist(m.propertyName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept JSON in constructor and return object', function() {
|
it('should accept JSON in constructor and return object', function () {
|
||||||
var m = new Model({
|
var m = new Model({
|
||||||
propertyName: '{"foo": "bar"}'
|
propertyName: '{"foo": "bar"}'
|
||||||
});
|
});
|
||||||
|
@ -23,14 +23,14 @@ describe('JSON property', function() {
|
||||||
m.propertyName.foo.should.equal('bar');
|
m.propertyName.foo.should.equal('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept object in setter and return object', function() {
|
it('should accept object in setter and return object', function () {
|
||||||
var m = new Model;
|
var m = new Model;
|
||||||
m.propertyName = {"foo": "bar"};
|
m.propertyName = {"foo": "bar"};
|
||||||
m.propertyName.should.be.an.Object;
|
m.propertyName.should.be.an.Object;
|
||||||
m.propertyName.foo.should.equal('bar');
|
m.propertyName.foo.should.equal('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept string in setter and return string', function() {
|
it('should accept string in setter and return string', function () {
|
||||||
var m = new Model;
|
var m = new Model;
|
||||||
m.propertyName = '{"foo": "bar"}';
|
m.propertyName = '{"foo": "bar"}';
|
||||||
m.propertyName.should.be.a.String;
|
m.propertyName.should.be.a.String;
|
||||||
|
|
|
@ -3,7 +3,7 @@ var should = require('./init.js');
|
||||||
|
|
||||||
var loopbackData = require('../');
|
var loopbackData = require('../');
|
||||||
|
|
||||||
describe('loopback-datasource-juggler', function() {
|
describe('loopback-datasource-juggler', function () {
|
||||||
it('should expose version', function () {
|
it('should expose version', function () {
|
||||||
loopbackData.version.should.equal(require('../package.json').version);
|
loopbackData.version.should.equal(require('../package.json').version);
|
||||||
});
|
});
|
||||||
|
|
|
@ -62,7 +62,7 @@ describe('ModelBuilder define model', function () {
|
||||||
try {
|
try {
|
||||||
var user = new User({name: 'Joe', age: 20});
|
var user = new User({name: 'Joe', age: 20});
|
||||||
assert(false, 'The code should have thrown an error');
|
assert(false, 'The code should have thrown an error');
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
assert(true, 'The code is expected to throw an error');
|
assert(true, 'The code is expected to throw an error');
|
||||||
}
|
}
|
||||||
done(null, User);
|
done(null, User);
|
||||||
|
@ -98,7 +98,6 @@ describe('ModelBuilder define model', function () {
|
||||||
done(null, User);
|
done(null, User);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should be able to define nesting models', function (done) {
|
it('should be able to define nesting models', function (done) {
|
||||||
var modelBuilder = new ModelBuilder();
|
var modelBuilder = new ModelBuilder();
|
||||||
|
|
||||||
|
@ -116,10 +115,12 @@ describe('ModelBuilder define model', function () {
|
||||||
zipCode: String,
|
zipCode: String,
|
||||||
country: String
|
country: String
|
||||||
},
|
},
|
||||||
emails: [{
|
emails: [
|
||||||
|
{
|
||||||
label: String,
|
label: String,
|
||||||
email: String
|
email: String
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
friends: [String]
|
friends: [String]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -134,7 +135,9 @@ describe('ModelBuilder define model', function () {
|
||||||
var user = new User({
|
var user = new User({
|
||||||
name: 'Joe', age: 20,
|
name: 'Joe', age: 20,
|
||||||
address: {street: '123 Main St', 'city': 'San Jose', state: 'CA'},
|
address: {street: '123 Main St', 'city': 'San Jose', state: 'CA'},
|
||||||
emails: [{label: 'work', email: 'xyz@sample.com'}],
|
emails: [
|
||||||
|
{label: 'work', email: 'xyz@sample.com'}
|
||||||
|
],
|
||||||
friends: ['Mary', 'John']
|
friends: ['Mary', 'John']
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -189,10 +192,8 @@ describe('ModelBuilder define model', function () {
|
||||||
done(null, User);
|
done(null, User);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('DataSource define model', function () {
|
describe('DataSource define model', function () {
|
||||||
it('should be able to define plain models', function () {
|
it('should be able to define plain models', function () {
|
||||||
var ds = new DataSource('memory');
|
var ds = new DataSource('memory');
|
||||||
|
@ -323,7 +324,7 @@ describe('DataSource define model', function () {
|
||||||
try {
|
try {
|
||||||
var user = new User({name: 'Joe', age: 20});
|
var user = new User({name: 'Joe', age: 20});
|
||||||
assert(false, 'The code should have thrown an error');
|
assert(false, 'The code should have thrown an error');
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
assert(true, 'The code is expected to throw an error');
|
assert(true, 'The code is expected to throw an error');
|
||||||
}
|
}
|
||||||
done(null, User);
|
done(null, User);
|
||||||
|
@ -342,7 +343,7 @@ describe('DataSource define model', function () {
|
||||||
user.should.have.property('age', 20);
|
user.should.have.property('age', 20);
|
||||||
user.should.not.have.property('bio');
|
user.should.not.have.property('bio');
|
||||||
|
|
||||||
User.findById(user.id, function(err, user) {
|
User.findById(user.id, function (err, user) {
|
||||||
user.should.be.a('object').and.have.property('name', 'Joe');
|
user.should.be.a('object').and.have.property('name', 'Joe');
|
||||||
user.should.have.property('name', 'Joe');
|
user.should.have.property('name', 'Joe');
|
||||||
user.should.have.property('age', 20);
|
user.should.have.property('age', 20);
|
||||||
|
@ -395,21 +396,20 @@ describe('DataSource define model', function () {
|
||||||
try {
|
try {
|
||||||
var user = new User({name: 'Joe', age: 20});
|
var user = new User({name: 'Joe', age: 20});
|
||||||
assert(false, 'The code should have thrown an error');
|
assert(false, 'The code should have thrown an error');
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
assert(true, 'The code is expected to throw an error');
|
assert(true, 'The code is expected to throw an error');
|
||||||
}
|
}
|
||||||
done(null, User);
|
done(null, User);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should change the property value for save if strict=false', function (done) {
|
it('should change the property value for save if strict=false', function (done) {
|
||||||
var ds = new DataSource('memory');// define models
|
var ds = new DataSource('memory');// define models
|
||||||
var Post = ds.define('Post');
|
var Post = ds.define('Post');
|
||||||
|
|
||||||
Post.create({price: 900}, function(err, post) {
|
Post.create({price: 900}, function (err, post) {
|
||||||
assert.equal(post.price, 900);
|
assert.equal(post.price, 900);
|
||||||
post.price = 1000;
|
post.price = 1000;
|
||||||
post.save(function(err, result) {
|
post.save(function (err, result) {
|
||||||
assert.equal(1000, result.price);
|
assert.equal(1000, result.price);
|
||||||
done(err, result);
|
done(err, result);
|
||||||
});
|
});
|
||||||
|
@ -424,8 +424,10 @@ describe('Load models with base', function () {
|
||||||
|
|
||||||
var User = ds.define('User', {name: String});
|
var User = ds.define('User', {name: String});
|
||||||
|
|
||||||
User.staticMethod = function staticMethod() {};
|
User.staticMethod = function staticMethod() {
|
||||||
User.prototype.instanceMethod = function instanceMethod() {};
|
};
|
||||||
|
User.prototype.instanceMethod = function instanceMethod() {
|
||||||
|
};
|
||||||
|
|
||||||
var Customer = ds.define('Customer', {vip: Boolean}, {base: 'User'});
|
var Customer = ds.define('Customer', {vip: Boolean}, {base: 'User'});
|
||||||
|
|
||||||
|
@ -433,10 +435,9 @@ describe('Load models with base', function () {
|
||||||
assert(Customer.staticMethod === User.staticMethod);
|
assert(Customer.staticMethod === User.staticMethod);
|
||||||
assert(Customer.prototype.instanceMethod === User.prototype.instanceMethod);
|
assert(Customer.prototype.instanceMethod === User.prototype.instanceMethod);
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var Customer1 = ds.define('Customer1', {vip: Boolean}, {base: 'User1'});
|
var Customer1 = ds.define('Customer1', {vip: Boolean}, {base: 'User1'});
|
||||||
} catch(e) {
|
} catch (e) {
|
||||||
assert(e);
|
assert(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,45 +445,45 @@ describe('Load models with base', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DataSource constructor', function() {
|
describe('DataSource constructor', function () {
|
||||||
// Mocked require
|
// Mocked require
|
||||||
var loader = function(name) {
|
var loader = function (name) {
|
||||||
return {
|
return {
|
||||||
name: name
|
name: name
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should resolve connector by path', function() {
|
it('should resolve connector by path', function () {
|
||||||
var connector = DataSource._resolveConnector(__dirname + '/../lib/connectors/memory');
|
var connector = DataSource._resolveConnector(__dirname + '/../lib/connectors/memory');
|
||||||
assert(connector.connector);
|
assert(connector.connector);
|
||||||
});
|
});
|
||||||
it('should resolve connector by internal name', function() {
|
it('should resolve connector by internal name', function () {
|
||||||
var connector = DataSource._resolveConnector('memory');
|
var connector = DataSource._resolveConnector('memory');
|
||||||
assert(connector.connector);
|
assert(connector.connector);
|
||||||
});
|
});
|
||||||
it('should try to resolve connector by module name starts with loopback-connector-', function() {
|
it('should try to resolve connector by module name starts with loopback-connector-', function () {
|
||||||
var connector = DataSource._resolveConnector('loopback-connector-xyz', loader);
|
var connector = DataSource._resolveConnector('loopback-connector-xyz', loader);
|
||||||
assert(connector.connector);
|
assert(connector.connector);
|
||||||
});
|
});
|
||||||
it('should try to resolve connector by short module name', function() {
|
it('should try to resolve connector by short module name', function () {
|
||||||
var connector = DataSource._resolveConnector('xyz', loader);
|
var connector = DataSource._resolveConnector('xyz', loader);
|
||||||
assert(connector.connector);
|
assert(connector.connector);
|
||||||
});
|
});
|
||||||
it('should try to resolve connector by full module name', function() {
|
it('should try to resolve connector by full module name', function () {
|
||||||
var connector = DataSource._resolveConnector('loopback-xyz', loader);
|
var connector = DataSource._resolveConnector('loopback-xyz', loader);
|
||||||
assert(connector.connector);
|
assert(connector.connector);
|
||||||
});
|
});
|
||||||
it('should fail to resolve connector by module name starts with loopback-connector-', function() {
|
it('should fail to resolve connector by module name starts with loopback-connector-', function () {
|
||||||
var connector = DataSource._resolveConnector('loopback-connector-xyz');
|
var connector = DataSource._resolveConnector('loopback-connector-xyz');
|
||||||
assert(!connector.connector);
|
assert(!connector.connector);
|
||||||
assert(connector.error.indexOf('loopback-connector-xyz') !== -1);
|
assert(connector.error.indexOf('loopback-connector-xyz') !== -1);
|
||||||
});
|
});
|
||||||
it('should fail to resolve connector by short module name', function() {
|
it('should fail to resolve connector by short module name', function () {
|
||||||
var connector = DataSource._resolveConnector('xyz');
|
var connector = DataSource._resolveConnector('xyz');
|
||||||
assert(!connector.connector);
|
assert(!connector.connector);
|
||||||
assert(connector.error.indexOf('loopback-connector-xyz') !== -1);
|
assert(connector.error.indexOf('loopback-connector-xyz') !== -1);
|
||||||
});
|
});
|
||||||
it('should fail to resolve connector by full module name', function() {
|
it('should fail to resolve connector by full module name', function () {
|
||||||
var connector = DataSource._resolveConnector('loopback-xyz');
|
var connector = DataSource._resolveConnector('loopback-xyz');
|
||||||
assert(!connector.connector);
|
assert(!connector.connector);
|
||||||
assert(connector.error.indexOf('loopback-connector-loopback-xyz') !== -1);
|
assert(connector.error.indexOf('loopback-connector-loopback-xyz') !== -1);
|
||||||
|
@ -627,7 +628,6 @@ describe('Load models with relations', function () {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DataAccessObject', function () {
|
describe('DataAccessObject', function () {
|
||||||
|
@ -741,7 +741,6 @@ describe('Load models from json', function () {
|
||||||
var path = require('path'),
|
var path = require('path'),
|
||||||
fs = require('fs');
|
fs = require('fs');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load LDL schemas from a json doc
|
* Load LDL schemas from a json doc
|
||||||
* @param schemaFile The dataSource json file
|
* @param schemaFile The dataSource json file
|
||||||
|
@ -803,8 +802,8 @@ describe('Load models from json', function () {
|
||||||
// The properties are defined at prototype level
|
// The properties are defined at prototype level
|
||||||
assert.equal(Object.keys(customer).length, 0);
|
assert.equal(Object.keys(customer).length, 0);
|
||||||
var count = 0;
|
var count = 0;
|
||||||
for(var p in customer) {
|
for (var p in customer) {
|
||||||
if(typeof customer[p] !== 'function') {
|
if (typeof customer[p] !== 'function') {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -831,7 +830,7 @@ describe('Load models from json', function () {
|
||||||
relations: {
|
relations: {
|
||||||
posts: {
|
posts: {
|
||||||
type: 'hasMany',
|
type: 'hasMany',
|
||||||
model:'Post'
|
model: 'Post'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -850,7 +849,7 @@ describe('Load models from json', function () {
|
||||||
relations: {
|
relations: {
|
||||||
orders: {
|
orders: {
|
||||||
type: 'hasMany',
|
type: 'hasMany',
|
||||||
model:'Order'
|
model: 'Order'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -868,7 +867,7 @@ describe('Load models from json', function () {
|
||||||
relations: {
|
relations: {
|
||||||
posts: {
|
posts: {
|
||||||
type: 'hasMany',
|
type: 'hasMany',
|
||||||
model:'Post'
|
model: 'Post'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
strict: false
|
strict: false
|
||||||
|
@ -891,11 +890,11 @@ describe('Load models from json', function () {
|
||||||
relations: {
|
relations: {
|
||||||
posts: {
|
posts: {
|
||||||
type: 'hasMany',
|
type: 'hasMany',
|
||||||
model:'Post'
|
model: 'Post'
|
||||||
},
|
},
|
||||||
orders: {
|
orders: {
|
||||||
type: 'hasMany',
|
type: 'hasMany',
|
||||||
model:'Order'
|
model: 'Order'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
strict: false
|
strict: false
|
||||||
|
@ -905,31 +904,30 @@ describe('Load models from json', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DataSource constructor', function(){
|
describe('DataSource constructor', function () {
|
||||||
it('Takes url as the settings', function() {
|
it('Takes url as the settings', function () {
|
||||||
var ds = new DataSource('memory://localhost/mydb?x=1');
|
var ds = new DataSource('memory://localhost/mydb?x=1');
|
||||||
assert.equal(ds.connector.name, 'memory');
|
assert.equal(ds.connector.name, 'memory');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Takes connector name', function() {
|
it('Takes connector name', function () {
|
||||||
var ds = new DataSource('memory');
|
var ds = new DataSource('memory');
|
||||||
assert.equal(ds.connector.name, 'memory');
|
assert.equal(ds.connector.name, 'memory');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Takes settings object', function() {
|
it('Takes settings object', function () {
|
||||||
var ds = new DataSource({connector: 'memory'});
|
var ds = new DataSource({connector: 'memory'});
|
||||||
assert.equal(ds.connector.name, 'memory');
|
assert.equal(ds.connector.name, 'memory');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Takes settings object and name', function() {
|
it('Takes settings object and name', function () {
|
||||||
var ds = new DataSource('x', {connector: 'memory'});
|
var ds = new DataSource('x', {connector: 'memory'});
|
||||||
assert.equal(ds.connector.name, 'memory');
|
assert.equal(ds.connector.name, 'memory');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Injected methods from connectors', function () {
|
||||||
describe('Injected methods from connectors', function(){
|
it('are not shared across models for remote methods', function () {
|
||||||
it('are not shared across models for remote methods', function() {
|
|
||||||
var ds = new DataSource('memory');
|
var ds = new DataSource('memory');
|
||||||
var M1 = ds.createModel('M1');
|
var M1 = ds.createModel('M1');
|
||||||
var M2 = ds.createModel('M2');
|
var M2 = ds.createModel('M2');
|
||||||
|
@ -942,7 +940,7 @@ describe('Injected methods from connectors', function(){
|
||||||
assert.equal(M2.create.shared, true, 'M2.create should stay remotable');
|
assert.equal(M2.create.shared, true, 'M2.create should stay remotable');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('are not shared across models for non-remote methods', function() {
|
it('are not shared across models for non-remote methods', function () {
|
||||||
var ds = new DataSource('memory');
|
var ds = new DataSource('memory');
|
||||||
var M1 = ds.createModel('M1');
|
var M1 = ds.createModel('M1');
|
||||||
var M2 = ds.createModel('M2');
|
var M2 = ds.createModel('M2');
|
||||||
|
@ -965,9 +963,8 @@ describe('Injected methods from connectors', function(){
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('ModelBuilder options.models', function () {
|
||||||
describe('ModelBuilder options.models', function(){
|
it('should inject model classes from models', function () {
|
||||||
it('should inject model classes from models', function() {
|
|
||||||
var builder = new ModelBuilder();
|
var builder = new ModelBuilder();
|
||||||
var M1 = builder.define('M1');
|
var M1 = builder.define('M1');
|
||||||
var M2 = builder.define('M2', {}, {models: {
|
var M2 = builder.define('M2', {}, {models: {
|
||||||
|
@ -977,7 +974,7 @@ describe('ModelBuilder options.models', function(){
|
||||||
assert.equal(M2.M1, M1, 'M1 should be injected to M2');
|
assert.equal(M2.M1, M1, 'M1 should be injected to M2');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inject model classes by name in the models', function() {
|
it('should inject model classes by name in the models', function () {
|
||||||
var builder = new ModelBuilder();
|
var builder = new ModelBuilder();
|
||||||
var M1 = builder.define('M1');
|
var M1 = builder.define('M1');
|
||||||
var M2 = builder.define('M2', {}, {models: {
|
var M2 = builder.define('M2', {}, {models: {
|
||||||
|
@ -988,7 +985,7 @@ describe('ModelBuilder options.models', function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inject model classes by name in the models before the class is defined',
|
it('should inject model classes by name in the models before the class is defined',
|
||||||
function() {
|
function () {
|
||||||
var builder = new ModelBuilder();
|
var builder = new ModelBuilder();
|
||||||
var M2 = builder.define('M2', {}, {models: {
|
var M2 = builder.define('M2', {}, {models: {
|
||||||
'M1': 'M1'
|
'M1': 'M1'
|
||||||
|
|
|
@ -4,9 +4,9 @@ var should = require('./init.js');
|
||||||
var db, Person;
|
var db, Person;
|
||||||
var ValidationError = require('..').ValidationError;
|
var ValidationError = require('..').ValidationError;
|
||||||
|
|
||||||
describe('manipulation', function() {
|
describe('manipulation', function () {
|
||||||
|
|
||||||
before(function(done) {
|
before(function (done) {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
|
|
||||||
Person = db.define('Person', {
|
Person = db.define('Person', {
|
||||||
|
@ -22,18 +22,18 @@ describe('manipulation', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('create', function() {
|
describe('create', function () {
|
||||||
|
|
||||||
before(function(done) {
|
before(function (done) {
|
||||||
Person.destroyAll(done);
|
Person.destroyAll(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create instance', function(done) {
|
it('should create instance', function (done) {
|
||||||
Person.create({name: 'Anatoliy'}, function(err, p) {
|
Person.create({name: 'Anatoliy'}, function (err, p) {
|
||||||
p.name.should.equal('Anatoliy');
|
p.name.should.equal('Anatoliy');
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(p);
|
should.exist(p);
|
||||||
Person.findById(p.id, function(err, person) {
|
Person.findById(p.id, function (err, person) {
|
||||||
person.id.should.equal(p.id);
|
person.id.should.equal(p.id);
|
||||||
person.name.should.equal('Anatoliy');
|
person.name.should.equal('Anatoliy');
|
||||||
done();
|
done();
|
||||||
|
@ -41,8 +41,8 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return instance of object', function(done) {
|
it('should return instance of object', function (done) {
|
||||||
var person = Person.create(function(err, p) {
|
var person = Person.create(function (err, p) {
|
||||||
p.id.should.eql(person.id);
|
p.id.should.eql(person.id);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -51,8 +51,8 @@ describe('manipulation', function() {
|
||||||
should.not.exist(person.id);
|
should.not.exist(person.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work when called without callback', function(done) {
|
it('should work when called without callback', function (done) {
|
||||||
Person.afterCreate = function(next) {
|
Person.afterCreate = function (next) {
|
||||||
this.should.be.an.instanceOf(Person);
|
this.should.be.an.instanceOf(Person);
|
||||||
this.name.should.equal('Nickolay');
|
this.name.should.equal('Nickolay');
|
||||||
should.exist(this.id);
|
should.exist(this.id);
|
||||||
|
@ -63,12 +63,12 @@ describe('manipulation', function() {
|
||||||
Person.create({name: 'Nickolay'});
|
Person.create({name: 'Nickolay'});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create instance with blank data', function(done) {
|
it('should create instance with blank data', function (done) {
|
||||||
Person.create(function(err, p) {
|
Person.create(function (err, p) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(p);
|
should.exist(p);
|
||||||
should.not.exists(p.name);
|
should.not.exists(p.name);
|
||||||
Person.findById(p.id, function(err, person) {
|
Person.findById(p.id, function (err, person) {
|
||||||
person.id.should.equal(p.id);
|
person.id.should.equal(p.id);
|
||||||
should.not.exists(person.name);
|
should.not.exists(person.name);
|
||||||
done();
|
done();
|
||||||
|
@ -76,8 +76,8 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work when called with no data and callback', function(done) {
|
it('should work when called with no data and callback', function (done) {
|
||||||
Person.afterCreate = function(next) {
|
Person.afterCreate = function (next) {
|
||||||
this.should.be.an.instanceOf(Person);
|
this.should.be.an.instanceOf(Person);
|
||||||
should.not.exist(this.name);
|
should.not.exist(this.name);
|
||||||
should.exist(this.id);
|
should.exist(this.id);
|
||||||
|
@ -88,16 +88,20 @@ describe('manipulation', function() {
|
||||||
Person.create();
|
Person.create();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create batch of objects', function(done) {
|
it('should create batch of objects', function (done) {
|
||||||
var batch = [{name: 'Shaltay'}, {name: 'Boltay'}, {}];
|
var batch = [
|
||||||
Person.create(batch, function(e, ps) {
|
{name: 'Shaltay'},
|
||||||
|
{name: 'Boltay'},
|
||||||
|
{}
|
||||||
|
];
|
||||||
|
Person.create(batch,function (e, ps) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(ps);
|
should.exist(ps);
|
||||||
ps.should.be.instanceOf(Array);
|
ps.should.be.instanceOf(Array);
|
||||||
ps.should.have.lengthOf(batch.length);
|
ps.should.have.lengthOf(batch.length);
|
||||||
|
|
||||||
Person.validatesPresenceOf('name');
|
Person.validatesPresenceOf('name');
|
||||||
Person.create(batch, function(errors, persons) {
|
Person.create(batch,function (errors, persons) {
|
||||||
delete Person._validations;
|
delete Person._validations;
|
||||||
should.exist(errors);
|
should.exist(errors);
|
||||||
errors.should.have.lengthOf(batch.length);
|
errors.should.have.lengthOf(batch.length);
|
||||||
|
@ -114,26 +118,26 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('save', function() {
|
describe('save', function () {
|
||||||
|
|
||||||
it('should save new object', function(done) {
|
it('should save new object', function (done) {
|
||||||
var p = new Person;
|
var p = new Person;
|
||||||
p.save(function(err) {
|
p.save(function (err) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(p.id);
|
should.exist(p.id);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save existing object', function(done) {
|
it('should save existing object', function (done) {
|
||||||
Person.findOne(function(err, p) {
|
Person.findOne(function (err, p) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
p.name = 'Hans';
|
p.name = 'Hans';
|
||||||
p.propertyChanged('name').should.be.true;
|
p.propertyChanged('name').should.be.true;
|
||||||
p.save(function(err) {
|
p.save(function (err) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
p.propertyChanged('name').should.be.false;
|
p.propertyChanged('name').should.be.false;
|
||||||
Person.findOne(function(err, p) {
|
Person.findOne(function (err, p) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
p.name.should.equal('Hans');
|
p.name.should.equal('Hans');
|
||||||
p.propertyChanged('name').should.be.false;
|
p.propertyChanged('name').should.be.false;
|
||||||
|
@ -143,18 +147,18 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save invalid object (skipping validation)', function(done) {
|
it('should save invalid object (skipping validation)', function (done) {
|
||||||
Person.findOne(function(err, p) {
|
Person.findOne(function (err, p) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
p.isValid = function(done) {
|
p.isValid = function (done) {
|
||||||
process.nextTick(done);
|
process.nextTick(done);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
p.name = 'Nana';
|
p.name = 'Nana';
|
||||||
p.save(function(err) {
|
p.save(function (err) {
|
||||||
should.exist(err);
|
should.exist(err);
|
||||||
p.propertyChanged('name').should.be.true;
|
p.propertyChanged('name').should.be.true;
|
||||||
p.save({validate: false}, function(err) {
|
p.save({validate: false}, function (err) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
p.propertyChanged('name').should.be.false;
|
p.propertyChanged('name').should.be.false;
|
||||||
done();
|
done();
|
||||||
|
@ -163,14 +167,14 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save throw error on validation', function() {
|
it('should save throw error on validation', function () {
|
||||||
Person.findOne(function(err, p) {
|
Person.findOne(function (err, p) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
p.isValid = function(cb) {
|
p.isValid = function (cb) {
|
||||||
cb(false);
|
cb(false);
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
(function() {
|
(function () {
|
||||||
p.save({
|
p.save({
|
||||||
'throws': true
|
'throws': true
|
||||||
});
|
});
|
||||||
|
@ -180,19 +184,19 @@ describe('manipulation', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('updateAttributes', function() {
|
describe('updateAttributes', function () {
|
||||||
var person;
|
var person;
|
||||||
|
|
||||||
before(function(done) {
|
before(function (done) {
|
||||||
Person.destroyAll(function() {
|
Person.destroyAll(function () {
|
||||||
person = Person.create(done);
|
person = Person.create(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update one attribute', function(done) {
|
it('should update one attribute', function (done) {
|
||||||
person.updateAttribute('name', 'Paul Graham', function(err, p) {
|
person.updateAttribute('name', 'Paul Graham', function (err, p) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
Person.all(function(e, ps) {
|
Person.all(function (e, ps) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
ps.should.have.lengthOf(1);
|
ps.should.have.lengthOf(1);
|
||||||
ps.pop().name.should.equal('Paul Graham');
|
ps.pop().name.should.equal('Paul Graham');
|
||||||
|
@ -202,13 +206,13 @@ describe('manipulation', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('destroy', function() {
|
describe('destroy', function () {
|
||||||
|
|
||||||
it('should destroy record', function(done) {
|
it('should destroy record', function (done) {
|
||||||
Person.create(function(err, p){
|
Person.create(function (err, p) {
|
||||||
p.destroy(function(err) {
|
p.destroy(function (err) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
Person.exists(p.id, function(err, ex) {
|
Person.exists(p.id, function (err, ex) {
|
||||||
ex.should.not.be.ok;
|
ex.should.not.be.ok;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -233,8 +237,8 @@ describe('manipulation', function() {
|
||||||
it('should destroy filtered set of records');
|
it('should destroy filtered set of records');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('initialize', function() {
|
describe('initialize', function () {
|
||||||
it('should initialize object properly', function() {
|
it('should initialize object properly', function () {
|
||||||
var hw = 'Hello word',
|
var hw = 'Hello word',
|
||||||
now = Date.now(),
|
now = Date.now(),
|
||||||
person = new Person({name: hw});
|
person = new Person({name: hw});
|
||||||
|
|
|
@ -29,7 +29,6 @@ describe('ModelDefinition class', function () {
|
||||||
assert.equal(User.properties.joinedAt.type, Date);
|
assert.equal(User.properties.joinedAt.type, Date);
|
||||||
assert.equal(User.properties.age.type, Number);
|
assert.equal(User.properties.age.type, Number);
|
||||||
|
|
||||||
|
|
||||||
var json = User.toJSON();
|
var json = User.toJSON();
|
||||||
assert.equal(json.name, "User");
|
assert.equal(json.name, "User");
|
||||||
assert.equal(json.properties.name.type, "String");
|
assert.equal(json.properties.name.type, "String");
|
||||||
|
@ -40,7 +39,6 @@ describe('ModelDefinition class', function () {
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to define additional properties', function (done) {
|
it('should be able to define additional properties', function (done) {
|
||||||
|
@ -66,10 +64,8 @@ describe('ModelDefinition class', function () {
|
||||||
assert.equal(User.properties.id.type, Number);
|
assert.equal(User.properties.id.type, Number);
|
||||||
done();
|
done();
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should be able to define nesting models', function (done) {
|
it('should be able to define nesting models', function (done) {
|
||||||
var modelBuilder = new ModelBuilder();
|
var modelBuilder = new ModelBuilder();
|
||||||
|
|
||||||
|
@ -112,7 +108,6 @@ describe('ModelDefinition class', function () {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should be able to define referencing models', function (done) {
|
it('should be able to define referencing models', function (done) {
|
||||||
var modelBuilder = new ModelBuilder();
|
var modelBuilder = new ModelBuilder();
|
||||||
|
|
||||||
|
@ -140,7 +135,6 @@ describe('ModelDefinition class', function () {
|
||||||
assert.equal(User.properties.age.type, Number);
|
assert.equal(User.properties.age.type, Number);
|
||||||
assert.equal(User.properties.address.type, Address);
|
assert.equal(User.properties.address.type, Address);
|
||||||
|
|
||||||
|
|
||||||
var json = User.toJSON();
|
var json = User.toJSON();
|
||||||
assert.equal(json.name, "User");
|
assert.equal(json.name, "User");
|
||||||
assert.equal(json.properties.name.type, "String");
|
assert.equal(json.properties.name.type, "String");
|
||||||
|
@ -182,7 +176,6 @@ describe('ModelDefinition class', function () {
|
||||||
assert.equal(User.properties.age.type, Number);
|
assert.equal(User.properties.age.type, Number);
|
||||||
assert.equal(User.properties.address.type, Address);
|
assert.equal(User.properties.address.type, Address);
|
||||||
|
|
||||||
|
|
||||||
var json = User.toJSON();
|
var json = User.toJSON();
|
||||||
assert.equal(json.name, "User");
|
assert.equal(json.name, "User");
|
||||||
assert.equal(json.properties.name.type, "String");
|
assert.equal(json.properties.name.type, "String");
|
||||||
|
|
|
@ -15,14 +15,12 @@ schemas =
|
||||||
url: 'http://localhost:5984/nano-test'
|
url: 'http://localhost:5984/nano-test'
|
||||||
|
|
||||||
testOrm = (dataSource) ->
|
testOrm = (dataSource) ->
|
||||||
|
|
||||||
User = Post = 'unknown'
|
User = Post = 'unknown'
|
||||||
maxUsers = 100
|
maxUsers = 100
|
||||||
maxPosts = 50000
|
maxPosts = 50000
|
||||||
users = []
|
users = []
|
||||||
|
|
||||||
it 'should define simple', (test) ->
|
it 'should define simple', (test) ->
|
||||||
|
|
||||||
User = dataSource.define 'User', {
|
User = dataSource.define 'User', {
|
||||||
name: String,
|
name: String,
|
||||||
bio: Text,
|
bio: Text,
|
||||||
|
@ -51,7 +49,8 @@ testOrm = (dataSource) ->
|
||||||
|
|
||||||
it 'should create bunch of data', (test) ->
|
it 'should create bunch of data', (test) ->
|
||||||
wait = maxPosts
|
wait = maxPosts
|
||||||
done = -> test.done() if --wait == 0
|
done = ->
|
||||||
|
test.done() if --wait == 0
|
||||||
rnd = (title) ->
|
rnd = (title) ->
|
||||||
{
|
{
|
||||||
userId: users[Math.floor(Math.random() * maxUsers)].id
|
userId: users[Math.floor(Math.random() * maxUsers)].id
|
||||||
|
@ -61,11 +60,13 @@ testOrm = (dataSource) ->
|
||||||
|
|
||||||
it 'do some queries using foreign keys', (test) ->
|
it 'do some queries using foreign keys', (test) ->
|
||||||
wait = 4
|
wait = 4
|
||||||
done = -> test.done() if --wait == 0
|
done = ->
|
||||||
|
test.done() if --wait == 0
|
||||||
ts = Date.now()
|
ts = Date.now()
|
||||||
query = (num) ->
|
query = (num) ->
|
||||||
users[num].posts { title: 'Post number 3' }, (err, collection) ->
|
users[num].posts { title: 'Post number 3' }, (err, collection) ->
|
||||||
console.log('User ' + num + ':', collection.length, 'posts in', Date.now() - ts,'ms')
|
console.log('User ' + num + ':', collection.length, 'posts in',
|
||||||
|
Date.now() - ts, 'ms')
|
||||||
done()
|
done()
|
||||||
query num for num in [0..4]
|
query num for num in [0..4]
|
||||||
|
|
||||||
|
|
|
@ -3,18 +3,18 @@ var should = require('./init.js');
|
||||||
|
|
||||||
var db, Book, Chapter, Author, Reader;
|
var db, Book, Chapter, Author, Reader;
|
||||||
|
|
||||||
describe('relations', function() {
|
describe('relations', function () {
|
||||||
before(function(done) {
|
before(function (done) {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
Book = db.define('Book', {name: String});
|
Book = db.define('Book', {name: String});
|
||||||
Chapter = db.define('Chapter', {name: {type: String, index: true}});
|
Chapter = db.define('Chapter', {name: {type: String, index: true}});
|
||||||
Author = db.define('Author', {name: String});
|
Author = db.define('Author', {name: String});
|
||||||
Reader = db.define('Reader', {name: String});
|
Reader = db.define('Reader', {name: String});
|
||||||
|
|
||||||
db.automigrate(function() {
|
db.automigrate(function () {
|
||||||
Book.destroyAll(function() {
|
Book.destroyAll(function () {
|
||||||
Chapter.destroyAll(function() {
|
Chapter.destroyAll(function () {
|
||||||
Author.destroyAll(function() {
|
Author.destroyAll(function () {
|
||||||
Reader.destroyAll(done);
|
Reader.destroyAll(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -22,12 +22,12 @@ describe('relations', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function() {
|
after(function () {
|
||||||
db.disconnect();
|
db.disconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hasMany', function() {
|
describe('hasMany', function () {
|
||||||
it('can be declared in different ways', function(done) {
|
it('can be declared in different ways', function (done) {
|
||||||
Book.hasMany(Chapter);
|
Book.hasMany(Chapter);
|
||||||
Book.hasMany(Reader, {as: 'users'});
|
Book.hasMany(Reader, {as: 'users'});
|
||||||
Book.hasMany(Author, {foreignKey: 'projectId'});
|
Book.hasMany(Author, {foreignKey: 'projectId'});
|
||||||
|
@ -41,7 +41,7 @@ describe('relations', function() {
|
||||||
db.automigrate(done);
|
db.automigrate(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be declared in short form', function(done) {
|
it('can be declared in short form', function (done) {
|
||||||
Author.hasMany('readers');
|
Author.hasMany('readers');
|
||||||
(new Author).readers.should.be.an.instanceOf(Function);
|
(new Author).readers.should.be.an.instanceOf(Function);
|
||||||
Object.keys((new Reader).toObject()).should.include('authorId');
|
Object.keys((new Reader).toObject()).should.include('authorId');
|
||||||
|
@ -49,17 +49,17 @@ describe('relations', function() {
|
||||||
db.autoupdate(done);
|
db.autoupdate(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should build record on scope', function(done) {
|
it('should build record on scope', function (done) {
|
||||||
Book.create(function(err, book) {
|
Book.create(function (err, book) {
|
||||||
var c = book.chapters.build();
|
var c = book.chapters.build();
|
||||||
c.bookId.should.equal(book.id);
|
c.bookId.should.equal(book.id);
|
||||||
c.save(done);
|
c.save(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create record on scope', function(done) {
|
it('should create record on scope', function (done) {
|
||||||
Book.create(function(err, book) {
|
Book.create(function (err, book) {
|
||||||
book.chapters.create(function(err, c) {
|
book.chapters.create(function (err, c) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(c);
|
should.exist(c);
|
||||||
c.bookId.should.equal(book.id);
|
c.bookId.should.equal(book.id);
|
||||||
|
@ -68,23 +68,23 @@ describe('relations', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('should fetch all scoped instances', function(done) {
|
it.skip('should fetch all scoped instances', function (done) {
|
||||||
Book.create(function(err, book) {
|
Book.create(function (err, book) {
|
||||||
book.chapters.create({name: 'a'}, function() {
|
book.chapters.create({name: 'a'}, function () {
|
||||||
book.chapters.create({name: 'z'}, function() {
|
book.chapters.create({name: 'z'}, function () {
|
||||||
book.chapters.create({name: 'c'}, function() {
|
book.chapters.create({name: 'c'}, function () {
|
||||||
fetch(book);
|
fetch(book);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
function fetch(book) {
|
function fetch(book) {
|
||||||
book.chapters(function(err, ch) {
|
book.chapters(function (err, ch) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(ch);
|
should.exist(ch);
|
||||||
ch.should.have.lengthOf(3);
|
ch.should.have.lengthOf(3);
|
||||||
|
|
||||||
book.chapters({order: 'name DESC'}, function(e, c) {
|
book.chapters({order: 'name DESC'}, function (e, c) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(c);
|
should.exist(c);
|
||||||
c.shift().name.should.equal('z');
|
c.shift().name.should.equal('z');
|
||||||
|
@ -95,13 +95,13 @@ describe('relations', function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find scoped record', function(done) {
|
it('should find scoped record', function (done) {
|
||||||
var id;
|
var id;
|
||||||
Book.create(function(err, book) {
|
Book.create(function (err, book) {
|
||||||
book.chapters.create({name: 'a'}, function(err, ch) {
|
book.chapters.create({name: 'a'}, function (err, ch) {
|
||||||
id = ch.id;
|
id = ch.id;
|
||||||
book.chapters.create({name: 'z'}, function() {
|
book.chapters.create({name: 'z'}, function () {
|
||||||
book.chapters.create({name: 'c'}, function() {
|
book.chapters.create({name: 'c'}, function () {
|
||||||
fetch(book);
|
fetch(book);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -109,7 +109,7 @@ describe('relations', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
function fetch(book) {
|
function fetch(book) {
|
||||||
book.chapters.findById(id, function(err, ch) {
|
book.chapters.findById(id, function (err, ch) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(ch);
|
should.exist(ch);
|
||||||
ch.id.should.equal(id);
|
ch.id.should.equal(id);
|
||||||
|
@ -119,10 +119,10 @@ describe('relations', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('belongsTo', function() {
|
describe('belongsTo', function () {
|
||||||
var List, Item, Fear, Mind;
|
var List, Item, Fear, Mind;
|
||||||
|
|
||||||
it('can be declared in different ways', function() {
|
it('can be declared in different ways', function () {
|
||||||
List = db.define('List', {name: String});
|
List = db.define('List', {name: String});
|
||||||
Item = db.define('Item', {name: String});
|
Item = db.define('Item', {name: String});
|
||||||
Fear = db.define('Fear');
|
Fear = db.define('Fear');
|
||||||
|
@ -140,14 +140,14 @@ describe('relations', function() {
|
||||||
// (new Fear).mind.build().should.be.an.instanceOf(Mind);
|
// (new Fear).mind.build().should.be.an.instanceOf(Mind);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can be used to query data', function(done) {
|
it('can be used to query data', function (done) {
|
||||||
List.hasMany('todos', {model: Item});
|
List.hasMany('todos', {model: Item});
|
||||||
db.automigrate(function() {
|
db.automigrate(function () {
|
||||||
List.create(function(e, list) {
|
List.create(function (e, list) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(list);
|
should.exist(list);
|
||||||
list.todos.create(function(err, todo) {
|
list.todos.create(function (err, todo) {
|
||||||
todo.list(function(e, l) {
|
todo.list(function (e, l) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(l);
|
should.exist(l);
|
||||||
l.should.be.an.instanceOf(List);
|
l.should.be.an.instanceOf(List);
|
||||||
|
@ -159,11 +159,11 @@ describe('relations', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('could accept objects when creating on scope', function(done) {
|
it('could accept objects when creating on scope', function (done) {
|
||||||
List.create(function(e, list) {
|
List.create(function (e, list) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(list);
|
should.exist(list);
|
||||||
Item.create({list: list}, function(err, item) {
|
Item.create({list: list}, function (err, item) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(item);
|
should.exist(item);
|
||||||
should.exist(item.listId);
|
should.exist(item.listId);
|
||||||
|
@ -176,28 +176,28 @@ describe('relations', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hasAndBelongsToMany', function() {
|
describe('hasAndBelongsToMany', function () {
|
||||||
var Article, Tag, ArticleTag;
|
var Article, Tag, ArticleTag;
|
||||||
it('can be declared', function(done) {
|
it('can be declared', function (done) {
|
||||||
Article = db.define('Article', {title: String});
|
Article = db.define('Article', {title: String});
|
||||||
Tag = db.define('Tag', {name: String});
|
Tag = db.define('Tag', {name: String});
|
||||||
Article.hasAndBelongsToMany('tags');
|
Article.hasAndBelongsToMany('tags');
|
||||||
ArticleTag = db.models.ArticleTag;
|
ArticleTag = db.models.ArticleTag;
|
||||||
db.automigrate(function() {
|
db.automigrate(function () {
|
||||||
Article.destroyAll(function() {
|
Article.destroyAll(function () {
|
||||||
Tag.destroyAll(function() {
|
Tag.destroyAll(function () {
|
||||||
ArticleTag.destroyAll(done)
|
ArticleTag.destroyAll(done)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow to create instances on scope', function(done) {
|
it('should allow to create instances on scope', function (done) {
|
||||||
Article.create(function(e, article) {
|
Article.create(function (e, article) {
|
||||||
article.tags.create({name: 'popular'}, function(e, t) {
|
article.tags.create({name: 'popular'}, function (e, t) {
|
||||||
t.should.be.an.instanceOf(Tag);
|
t.should.be.an.instanceOf(Tag);
|
||||||
// console.log(t);
|
// console.log(t);
|
||||||
ArticleTag.findOne(function(e, at) {
|
ArticleTag.findOne(function (e, at) {
|
||||||
should.exist(at);
|
should.exist(at);
|
||||||
at.tagId.toString().should.equal(t.id.toString());
|
at.tagId.toString().should.equal(t.id.toString());
|
||||||
at.articleId.toString().should.equal(article.id.toString());
|
at.articleId.toString().should.equal(article.id.toString());
|
||||||
|
@ -207,9 +207,9 @@ describe('relations', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow to fetch scoped instances', function(done) {
|
it('should allow to fetch scoped instances', function (done) {
|
||||||
Article.findOne(function(e, article) {
|
Article.findOne(function (e, article) {
|
||||||
article.tags(function(e, tags) {
|
article.tags(function (e, tags) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(tags);
|
should.exist(tags);
|
||||||
done();
|
done();
|
||||||
|
@ -217,10 +217,10 @@ describe('relations', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow to add connection with instance', function(done) {
|
it('should allow to add connection with instance', function (done) {
|
||||||
Article.findOne(function(e, article) {
|
Article.findOne(function (e, article) {
|
||||||
Tag.create({name: 'awesome'}, function(e, tag) {
|
Tag.create({name: 'awesome'}, function (e, tag) {
|
||||||
article.tags.add(tag, function(e, at) {
|
article.tags.add(tag, function (e, at) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
should.exist(at);
|
should.exist(at);
|
||||||
at.should.be.an.instanceOf(ArticleTag);
|
at.should.be.an.instanceOf(ArticleTag);
|
||||||
|
@ -232,14 +232,14 @@ describe('relations', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow to remove connection with instance', function(done) {
|
it('should allow to remove connection with instance', function (done) {
|
||||||
Article.findOne(function(e, article) {
|
Article.findOne(function (e, article) {
|
||||||
article.tags(function(e, tags) {
|
article.tags(function (e, tags) {
|
||||||
var len = tags.length;
|
var len = tags.length;
|
||||||
tags.should.not.be.empty;
|
tags.should.not.be.empty;
|
||||||
article.tags.remove(tags[0], function(e) {
|
article.tags.remove(tags[0], function (e) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
article.tags(true, function(e, tags) {
|
article.tags(true, function (e, tags) {
|
||||||
tags.should.have.lengthOf(len - 1);
|
tags.should.have.lengthOf(len - 1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,16 +3,16 @@ var should = require('./init.js');
|
||||||
|
|
||||||
var db = getSchema(), slave = getSchema(), Model, SlaveModel;
|
var db = getSchema(), slave = getSchema(), Model, SlaveModel;
|
||||||
|
|
||||||
describe('dataSource', function() {
|
describe('dataSource', function () {
|
||||||
|
|
||||||
it('should define Model', function() {
|
it('should define Model', function () {
|
||||||
Model = db.define('Model');
|
Model = db.define('Model');
|
||||||
Model.dataSource.should.eql(db);
|
Model.dataSource.should.eql(db);
|
||||||
var m = new Model;
|
var m = new Model;
|
||||||
m.getDataSource().should.eql(db);
|
m.getDataSource().should.eql(db);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should clone existing model', function() {
|
it('should clone existing model', function () {
|
||||||
SlaveModel = slave.copyModel(Model);
|
SlaveModel = slave.copyModel(Model);
|
||||||
SlaveModel.dataSource.should.eql(slave);
|
SlaveModel.dataSource.should.eql(slave);
|
||||||
slave.should.not.eql(db);
|
slave.should.not.eql(db);
|
||||||
|
@ -22,11 +22,11 @@ describe('dataSource', function() {
|
||||||
sm.getDataSource().should.eql(slave);
|
sm.getDataSource().should.eql(slave);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should automigrate', function(done) {
|
it('should automigrate', function (done) {
|
||||||
db.automigrate(done);
|
db.automigrate(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create transaction', function(done) {
|
it('should create transaction', function (done) {
|
||||||
var tr = db.transaction();
|
var tr = db.transaction();
|
||||||
tr.connected.should.be.false;
|
tr.connected.should.be.false;
|
||||||
tr.connecting.should.be.false;
|
tr.connecting.should.be.false;
|
||||||
|
@ -37,15 +37,15 @@ describe('dataSource', function() {
|
||||||
tr.connected.should.be.false;
|
tr.connected.should.be.false;
|
||||||
tr.connecting.should.be.true;
|
tr.connecting.should.be.true;
|
||||||
|
|
||||||
db.models.Model.count(function(err, c) {
|
db.models.Model.count(function (err, c) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(c);
|
should.exist(c);
|
||||||
c.should.equal(0);
|
c.should.equal(0);
|
||||||
called.should.be.false;
|
called.should.be.false;
|
||||||
tr.exec(function () {
|
tr.exec(function () {
|
||||||
setTimeout(function() {
|
setTimeout(function () {
|
||||||
called.should.be.true;
|
called.should.be.true;
|
||||||
db.models.Model.count(function(err, c) {
|
db.models.Model.count(function (err, c) {
|
||||||
c.should.equal(3);
|
c.should.equal(3);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,9 +3,9 @@ var should = require('./init.js');
|
||||||
|
|
||||||
var db, Railway, Station;
|
var db, Railway, Station;
|
||||||
|
|
||||||
describe('sc0pe', function() {
|
describe('sc0pe', function () {
|
||||||
|
|
||||||
before(function() {
|
before(function () {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
Railway = db.define('Railway', {
|
Railway = db.define('Railway', {
|
||||||
URID: {type: String, index: true}
|
URID: {type: String, index: true}
|
||||||
|
@ -19,15 +19,15 @@ describe('sc0pe', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function (done) {
|
||||||
Railway.destroyAll(function() {
|
Railway.destroyAll(function () {
|
||||||
Station.destroyAll(done);
|
Station.destroyAll(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should define scope with query', function(done) {
|
it('should define scope with query', function (done) {
|
||||||
Station.scope('active', {where: {isActive: true}});
|
Station.scope('active', {where: {isActive: true}});
|
||||||
Station.active.create(function(err, station) {
|
Station.active.create(function (err, station) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(station);
|
should.exist(station);
|
||||||
should.exist(station.isActive);
|
should.exist(station.isActive);
|
||||||
|
@ -36,10 +36,10 @@ describe('sc0pe', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow scope chaining', function(done) {
|
it('should allow scope chaining', function (done) {
|
||||||
Station.scope('active', {where: {isActive: true}});
|
Station.scope('active', {where: {isActive: true}});
|
||||||
Station.scope('subway', {where: {isUndeground: true}});
|
Station.scope('subway', {where: {isUndeground: true}});
|
||||||
Station.active.subway.create(function(err, station) {
|
Station.active.subway.create(function (err, station) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
should.exist(station);
|
should.exist(station);
|
||||||
station.isActive.should.be.true;
|
station.isActive.should.be.true;
|
||||||
|
@ -48,13 +48,13 @@ describe('sc0pe', function() {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should query all', function(done) {
|
it('should query all', function (done) {
|
||||||
Station.scope('active', {where: {isActive: true}});
|
Station.scope('active', {where: {isActive: true}});
|
||||||
Station.scope('inactive', {where: {isActive: false}});
|
Station.scope('inactive', {where: {isActive: false}});
|
||||||
Station.scope('ground', {where: {isUndeground: true}});
|
Station.scope('ground', {where: {isUndeground: true}});
|
||||||
Station.active.ground.create(function() {
|
Station.active.ground.create(function () {
|
||||||
Station.inactive.ground.create(function() {
|
Station.inactive.ground.create(function () {
|
||||||
Station.ground.inactive(function(err, ss) {
|
Station.ground.inactive(function (err, ss) {
|
||||||
ss.should.have.lengthOf(1);
|
ss.should.have.lengthOf(1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
/*
|
/*
|
||||||
if (!process.env.TRAVIS) {
|
if (!process.env.TRAVIS) {
|
||||||
var semicov = require('semicov');
|
var semicov = require('semicov');
|
||||||
semicov.init('lib', 'LoopbackData');
|
semicov.init('lib', 'LoopbackData');
|
||||||
process.on('exit', semicov.report);
|
process.on('exit', semicov.report);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
try {
|
try {
|
||||||
global.sinon = require('sinon');
|
global.sinon = require('sinon');
|
||||||
|
|
|
@ -4,10 +4,8 @@ var fieldsToArray = utils.fieldsToArray;
|
||||||
var removeUndefined = utils.removeUndefined;
|
var removeUndefined = utils.removeUndefined;
|
||||||
var mergeSettings = utils.mergeSettings;
|
var mergeSettings = utils.mergeSettings;
|
||||||
|
|
||||||
|
describe('util.fieldsToArray', function () {
|
||||||
describe('util.fieldsToArray', function(){
|
it('Turn objects and strings into an array of fields to include when finding models', function () {
|
||||||
it('Turn objects and strings into an array of fields to include when finding models', function() {
|
|
||||||
|
|
||||||
|
|
||||||
function sample(fields) {
|
function sample(fields) {
|
||||||
var properties = ['foo', 'bar', 'bat', 'baz'];
|
var properties = ['foo', 'bar', 'bat', 'baz'];
|
||||||
|
@ -30,8 +28,8 @@ describe('util.fieldsToArray', function(){
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('util.removeUndefined', function(){
|
describe('util.removeUndefined', function () {
|
||||||
it('Remove undefined values from the query object', function() {
|
it('Remove undefined values from the query object', function () {
|
||||||
var q1 = {where: {x: 1, y: undefined}};
|
var q1 = {where: {x: 1, y: undefined}};
|
||||||
should.deepEqual(removeUndefined(q1), {where: {x: 1}});
|
should.deepEqual(removeUndefined(q1), {where: {x: 1}});
|
||||||
|
|
||||||
|
@ -54,8 +52,8 @@ describe('util.removeUndefined', function(){
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('util.parseSettings', function(){
|
describe('util.parseSettings', function () {
|
||||||
it('Parse a full url into a settings object', function() {
|
it('Parse a full url into a settings object', function () {
|
||||||
var url = 'mongodb://x:y@localhost:27017/mydb?w=2';
|
var url = 'mongodb://x:y@localhost:27017/mydb?w=2';
|
||||||
var settings = utils.parseSettings(url);
|
var settings = utils.parseSettings(url);
|
||||||
should.equal(settings.hostname, 'localhost');
|
should.equal(settings.hostname, 'localhost');
|
||||||
|
@ -70,7 +68,7 @@ describe('util.parseSettings', function(){
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Parse a url without auth into a settings object', function() {
|
it('Parse a url without auth into a settings object', function () {
|
||||||
var url = 'mongodb://localhost:27017/mydb/abc?w=2';
|
var url = 'mongodb://localhost:27017/mydb/abc?w=2';
|
||||||
var settings = utils.parseSettings(url);
|
var settings = utils.parseSettings(url);
|
||||||
should.equal(settings.hostname, 'localhost');
|
should.equal(settings.hostname, 'localhost');
|
||||||
|
@ -85,7 +83,7 @@ describe('util.parseSettings', function(){
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Parse a url with complex query into a settings object', function() {
|
it('Parse a url with complex query into a settings object', function () {
|
||||||
var url = 'mysql://127.0.0.1:3306/mydb?x[a]=1&x[b]=2&engine=InnoDB';
|
var url = 'mysql://127.0.0.1:3306/mydb?x[a]=1&x[b]=2&engine=InnoDB';
|
||||||
var settings = utils.parseSettings(url);
|
var settings = utils.parseSettings(url);
|
||||||
should.equal(settings.hostname, '127.0.0.1');
|
should.equal(settings.hostname, '127.0.0.1');
|
||||||
|
@ -102,7 +100,7 @@ describe('util.parseSettings', function(){
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Parse a url without auth into a settings object', function() {
|
it('Parse a url without auth into a settings object', function () {
|
||||||
var url = 'memory://?x=1';
|
var url = 'memory://?x=1';
|
||||||
var settings = utils.parseSettings(url);
|
var settings = utils.parseSettings(url);
|
||||||
should.equal(settings.hostname, '');
|
should.equal(settings.hostname, '');
|
||||||
|
|
|
@ -16,9 +16,9 @@ function getValidAttributes() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('validations', function() {
|
describe('validations', function () {
|
||||||
|
|
||||||
before(function(done) {
|
before(function (done) {
|
||||||
db = getSchema();
|
db = getSchema();
|
||||||
User = db.define('User', {
|
User = db.define('User', {
|
||||||
email: String,
|
email: String,
|
||||||
|
@ -36,22 +36,22 @@ describe('validations', function() {
|
||||||
db.automigrate(done);
|
db.automigrate(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(function(done) {
|
beforeEach(function (done) {
|
||||||
User.destroyAll(function() {
|
User.destroyAll(function () {
|
||||||
delete User._validations;
|
delete User._validations;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function() {
|
after(function () {
|
||||||
db.disconnect();
|
db.disconnect();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('commons', function() {
|
describe('commons', function () {
|
||||||
|
|
||||||
describe('skipping', function() {
|
describe('skipping', function () {
|
||||||
|
|
||||||
it('should allow to skip using if: attribute', function() {
|
it('should allow to skip using if: attribute', function () {
|
||||||
User.validatesPresenceOf('pendingPeriod', {if: 'createdByAdmin'});
|
User.validatesPresenceOf('pendingPeriod', {if: 'createdByAdmin'});
|
||||||
var user = new User;
|
var user = new User;
|
||||||
user.createdByAdmin = true;
|
user.createdByAdmin = true;
|
||||||
|
@ -63,29 +63,29 @@ describe('validations', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('lifecycle', function() {
|
describe('lifecycle', function () {
|
||||||
|
|
||||||
it('should work on create', function(done) {
|
it('should work on create', function (done) {
|
||||||
delete User._validations;
|
delete User._validations;
|
||||||
User.validatesPresenceOf('name');
|
User.validatesPresenceOf('name');
|
||||||
User.create(function(e, u) {
|
User.create(function (e, u) {
|
||||||
should.exist(e);
|
should.exist(e);
|
||||||
User.create({name: 'Valid'}, function(e, d) {
|
User.create({name: 'Valid'}, function (e, d) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work on update', function(done) {
|
it('should work on update', function (done) {
|
||||||
delete User._validations;
|
delete User._validations;
|
||||||
User.validatesPresenceOf('name');
|
User.validatesPresenceOf('name');
|
||||||
User.create({name: 'Valid'}, function(e, d) {
|
User.create({name: 'Valid'}, function (e, d) {
|
||||||
d.updateAttribute('name', null, function(e) {
|
d.updateAttribute('name', null, function (e) {
|
||||||
should.exist(e);
|
should.exist(e);
|
||||||
e.should.be.instanceOf(Error);
|
e.should.be.instanceOf(Error);
|
||||||
e.should.be.instanceOf(ValidationError);
|
e.should.be.instanceOf(ValidationError);
|
||||||
d.updateAttribute('name', 'Vasiliy', function(e) {
|
d.updateAttribute('name', 'Vasiliy', function (e) {
|
||||||
should.not.exist(e);
|
should.not.exist(e);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -93,18 +93,18 @@ describe('validations', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return error code', function(done) {
|
it('should return error code', function (done) {
|
||||||
delete User._validations;
|
delete User._validations;
|
||||||
User.validatesPresenceOf('name');
|
User.validatesPresenceOf('name');
|
||||||
User.create(function(e, u) {
|
User.create(function (e, u) {
|
||||||
should.exist(e);
|
should.exist(e);
|
||||||
e.details.codes.name.should.eql(['presence']);
|
e.details.codes.name.should.eql(['presence']);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow to modify error after validation', function(done) {
|
it('should allow to modify error after validation', function (done) {
|
||||||
User.afterValidate = function(next) {
|
User.afterValidate = function (next) {
|
||||||
next();
|
next();
|
||||||
};
|
};
|
||||||
done();
|
done();
|
||||||
|
@ -113,9 +113,9 @@ describe('validations', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('presence', function() {
|
describe('presence', function () {
|
||||||
|
|
||||||
it('should validate presence', function() {
|
it('should validate presence', function () {
|
||||||
User.validatesPresenceOf('name', 'email');
|
User.validatesPresenceOf('name', 'email');
|
||||||
var u = new User;
|
var u = new User;
|
||||||
u.isValid().should.not.be.true;
|
u.isValid().should.not.be.true;
|
||||||
|
@ -124,7 +124,7 @@ describe('validations', function() {
|
||||||
u.isValid().should.be.true;
|
u.isValid().should.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should skip validation by property (if/unless)', function() {
|
it('should skip validation by property (if/unless)', function () {
|
||||||
User.validatesPresenceOf('domain', {unless: 'createdByScript'});
|
User.validatesPresenceOf('domain', {unless: 'createdByScript'});
|
||||||
|
|
||||||
var user = new User(getValidAttributes())
|
var user = new User(getValidAttributes())
|
||||||
|
@ -140,15 +140,15 @@ describe('validations', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('uniqueness', function() {
|
describe('uniqueness', function () {
|
||||||
it('should validate uniqueness', function(done) {
|
it('should validate uniqueness', function (done) {
|
||||||
User.validatesUniquenessOf('email');
|
User.validatesUniquenessOf('email');
|
||||||
var u = new User({email: 'hey'});
|
var u = new User({email: 'hey'});
|
||||||
Boolean(u.isValid(function(valid) {
|
Boolean(u.isValid(function (valid) {
|
||||||
valid.should.be.true;
|
valid.should.be.true;
|
||||||
u.save(function() {
|
u.save(function () {
|
||||||
var u2 = new User({email: 'hey'});
|
var u2 = new User({email: 'hey'});
|
||||||
u2.isValid(function(valid) {
|
u2.isValid(function (valid) {
|
||||||
valid.should.be.false;
|
valid.should.be.false;
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
@ -156,14 +156,14 @@ describe('validations', function() {
|
||||||
})).should.be.false;
|
})).should.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle same object modification', function(done) {
|
it('should handle same object modification', function (done) {
|
||||||
User.validatesUniquenessOf('email');
|
User.validatesUniquenessOf('email');
|
||||||
var u = new User({email: 'hey'});
|
var u = new User({email: 'hey'});
|
||||||
Boolean(u.isValid(function(valid) {
|
Boolean(u.isValid(function (valid) {
|
||||||
valid.should.be.true;
|
valid.should.be.true;
|
||||||
u.save(function() {
|
u.save(function () {
|
||||||
u.name = 'Goghi';
|
u.name = 'Goghi';
|
||||||
u.isValid(function(valid) {
|
u.isValid(function (valid) {
|
||||||
valid.should.be.true;
|
valid.should.be.true;
|
||||||
u.save(done);
|
u.save(done);
|
||||||
});
|
});
|
||||||
|
@ -174,28 +174,28 @@ describe('validations', function() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('format', function() {
|
describe('format', function () {
|
||||||
it('should validate format');
|
it('should validate format');
|
||||||
it('should overwrite default blank message with custom format message');
|
it('should overwrite default blank message with custom format message');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('numericality', function() {
|
describe('numericality', function () {
|
||||||
it('should validate numericality');
|
it('should validate numericality');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('inclusion', function() {
|
describe('inclusion', function () {
|
||||||
it('should validate inclusion');
|
it('should validate inclusion');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('exclusion', function() {
|
describe('exclusion', function () {
|
||||||
it('should validate exclusion');
|
it('should validate exclusion');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('length', function() {
|
describe('length', function () {
|
||||||
it('should validate length');
|
it('should validate length');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('custom', function() {
|
describe('custom', function () {
|
||||||
it('should validate using custom sync validation');
|
it('should validate using custom sync validation');
|
||||||
it('should validate using custom async validation');
|
it('should validate using custom async validation');
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue