Merge branch 'release/1.2.13' into production

This commit is contained in:
Miroslav Bajtoš 2014-01-27 10:15:12 +01:00
commit 758cea9f5c
56 changed files with 8844 additions and 8782 deletions

View File

@ -4,7 +4,9 @@ LoopBack DataSource Juggler is an ORM that provides a common set of interfaces
for interacting with databases, REST APIs, and other data sources. It was
initially forked from [JugglingDB](https://github.com/1602/jugglingdb).
For full documentation, see [StrongLoop Suite Documentation](http://docs.strongloop.com/display/DOC/Data+Source+Juggler).
**For full documentation, see the official StrongLoop documentation**:
* [Data sources and connectors](http://docs.strongloop.com/display/DOC/Data+sources+and+connectors)
* [Data Source Juggler](http://docs.strongloop.com/display/DOC/Data+Source+Juggler).
## Installation

View File

@ -58,12 +58,15 @@ The `DataSource` constructor is available from `loopback-datasource-juggler` mod
- connector: The name or instance of the connector module
- settings: An object of properties to configure the connector
```
var dataSource = new DataSource({
connector: require('loopback-connector-mongodb'),
host: 'localhost',
port: 27017,
database: 'mydb'
});
```
#### connector
@ -75,10 +78,11 @@ The `connector` argument passed the DataSource constructor can be one of the fol
to 'loopback-connector-<shortName>'
* A local module under ./connectors/<connectorName> folder
```
var ds1 = new DataSource('memory');
var ds2 = new DataSource('loopback-connector-mongodb'));
var ds3 = new DataSource(require('loopback-connector-oracle'));
```
**Note**: LoopBack provides a built-in connector named as `memory` to use in-memory
store for CRUD operations.

View File

@ -4,12 +4,14 @@ var modelBuilder = new ModelBuilder();
var Post = modelBuilder.define('Post', {
title: { type: String, length: 255 },
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 },
published: { type: Boolean, default: false, index: true }
});
// simplier way to describe model
// simpler way to describe model
var User = modelBuilder.define('User', {
name: String,
bio: ModelBuilder.Text,

View File

@ -15,14 +15,18 @@ var User = modelBuilder.define('User', {
zipCode: String,
country: String
},
emails: [{
emails: [
{
label: String,
email: String
}],
}
],
friends: [String]
});
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']});
console.log(user.toObject());

View File

@ -24,7 +24,6 @@ Customer.create({name: 'John'}, function (err, customer) {
});
});
Customer.hasMany(Order, {as: 'orders', foreignKey: 'customerId'});
Customer.create({name: 'Ray'}, function (err, customer) {
@ -41,7 +40,6 @@ Customer.create({name: 'Ray'}, function (err, customer) {
});
});
var Physician = ds.createModel('Physician', {
name: String
});
@ -72,7 +70,6 @@ Physician.create({name: 'Smith'}, function (err, physician) {
});
});
var Assembly = ds.createModel('Assembly', {
name: String
});

View File

@ -27,7 +27,6 @@ Connector.prototype.execute = function (command, params, callback) {
throw new Error('query method should be declared in connector');
};
/**
* Look up the data source by model name
* @param {String} model The model name
@ -59,7 +58,6 @@ Connector.prototype.idNames = function (model) {
return this.getDataSource(model).idNames(model);
};
/**
* Get the id index (sequence number, starting from 1)
* @param {String} model The model name
@ -126,6 +124,10 @@ Connector.prototype.setIdValue = function(model, data, value) {
}
};
Connector.prototype.getType = function () {
return this.type;
};

View File

@ -16,8 +16,14 @@ function CradleAdapter(client) {
function createdbif(client, callback) {
client.exists(function (err, exists) {
if (err) callback(err);
if (!exists) { client.create(function() { callback(); }); }
else { callback(); }
if (!exists) {
client.create(function () {
callback();
});
}
else {
callback();
}
});
}
@ -278,7 +284,8 @@ CradleAdapter.prototype.models = function(model, filter, callback, func) {
}
}
}, 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},
errorHandler(callback, function (res, cb) {
var docs = res.map(function (doc) {
return idealize(doc);
});

View File

@ -24,7 +24,8 @@ WebService.prototype.installPostProcessor = function installPostProcessor(descr)
if (model[column]) {
model[column] = new Date(model[column]);
}
};
}
;
};
descr.postProcessor = postProcessor;
@ -55,7 +56,8 @@ WebService.prototype.postProcessMultiple = function postProcessMultiple(model, d
if (data[i]) {
postProcessor(data[i]);
}
};
}
;
}
};

View File

@ -190,6 +190,7 @@ Neo4j.prototype.updateIndexes = function updateIndexes(model, node, cb) {
done();
var error = false;
function done(err) {
error = error || err;
if (--wait === 0) {

View File

@ -19,7 +19,6 @@ var utils = require('./utils');
var fieldsToArray = utils.fieldsToArray;
var removeUndefined = utils.removeUndefined;
/**
* DAO class - base class for all persist objects
* provides **common API** to access any database connector.
@ -94,7 +93,8 @@ DataAccessObject.create = function (data, callback) {
}
if (typeof callback !== 'function') {
callback = function () {};
callback = function () {
};
}
if (!data) {
@ -130,7 +130,6 @@ DataAccessObject.create = function (data, callback) {
}
}
var obj;
// if we come from save
if (data instanceof Model && !getIdValue(this, data)) {
@ -250,7 +249,6 @@ setRemoting(DataAccessObject.upsert, {
http: {verb: 'put', path: '/'}
});
/**
* Find one record, same as `all`, limited by 1 and return object, not collection,
* 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;
}
if (typeof callback === 'undefined') {
callback = function () {};
callback = function () {
};
}
var t = this;
@ -599,7 +598,6 @@ setRemoting(DataAccessObject.findOne, {
http: {verb: 'get', path: '/findOne'}
});
/**
* Destroy all matching records
* @param {Object} [where] An object that defines the criteria
@ -652,7 +650,6 @@ setRemoting(DataAccessObject.deleteById, {
http: {verb: 'del', path: '/:id'}
});
/**
* Return count of matched records
*
@ -671,7 +668,6 @@ DataAccessObject.count = function (where, cb) {
this.getDataSource().connector.count(this.modelName, cb, where);
};
// count ~ remoting attributes
setRemoting(DataAccessObject.count, {
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'}
});
/**
* Save instance. When instance haven't id, create method called instead.
* Triggers: validate, save, update | create
@ -695,7 +690,8 @@ DataAccessObject.prototype.save = function (options, callback) {
options = {};
}
callback = callback || function () {};
callback = callback || function () {
};
options = options || {};
if (!('validate' in options)) {
@ -752,7 +748,6 @@ DataAccessObject.prototype.save = function (options, callback) {
}
};
DataAccessObject.prototype.isNewRecord = function () {
return !getIdValue(this.constructor, this);
};
@ -788,7 +783,6 @@ DataAccessObject.prototype.destroy = function (cb) {
});
};
/**
* Update single attribute
*
@ -851,7 +845,8 @@ DataAccessObject.prototype.updateAttributes = function updateAttributes(data, cb
// update $was attrs
for (var key in data) {
inst.__dataWas[key] = inst.__data[key];
};
}
;
}
done.call(inst, function () {
saveDone.call(inst, function () {
@ -873,7 +868,6 @@ setRemoting(DataAccessObject.prototype.updateAttributes, {
http: {verb: 'put', path: '/'}
});
/**
* Reload object from persistence
*

View File

@ -15,8 +15,6 @@ var fs = require('fs');
var assert = require('assert');
var async = require('async');
var existsSync = fs.existsSync || path.existsSync;
/**
* Export public API
*/
@ -91,7 +89,8 @@ function DataSource(name, settings, modelBuilder) {
// DataAccessObject - connector defined or supply the default
var dao = (connector && connector.DataAccessObject) || this.constructor.DataAccessObject;
this.DataAccessObject = function() {};
this.DataAccessObject = function () {
};
// define DataAccessObject methods
Object.keys(dao).forEach(function (name) {
@ -129,15 +128,11 @@ function DataSource(name, settings, modelBuilder) {
}
util.inherits(DataSource, EventEmitter);
// allow child classes to supply a data access object
DataSource.DataAccessObject = DataAccessObject;
/**
* Set up the connector instance for backward compatibility with JugglingDB schema/adapter
* @private
@ -351,7 +346,6 @@ function isModelClass(cls) {
DataSource.relationTypes = ['belongsTo', 'hasMany', 'hasAndBelongsToMany'];
function isModelDataSourceAttached(model) {
return model && (!model.settings.unresolved) && (model.dataSource instanceof DataSource);
}
@ -524,7 +518,6 @@ DataSource.prototype.createModel = DataSource.prototype.define = function define
return modelClass;
};
/**
* Mixin DataAccessObject methods.
*
@ -684,7 +677,6 @@ DataSource.prototype.discoverModelDefinitions = function (options, cb) {
}
};
/**
* The synchronous version of discoverModelDefinitions
* @param {Object} options The options
@ -881,7 +873,7 @@ DataSource.prototype.discoverExportedForeignKeysSync= function(modelName, option
return this.connector.discoverExportedForeignKeysSync(modelName, options);
}
return null;
}
};
function capitalize(str) {
if (!str) {
@ -1102,7 +1094,6 @@ DataSource.prototype.discoverSchemas = function (modelName, options, cb) {
});
};
/**
* Discover schema from a given table/view synchronously
*
@ -1419,7 +1410,6 @@ DataSource.prototype.idNames = function (modelName) {
return this.getModelDefinition(modelName).idNames();
};
/**
* Define foreign key to another model
* @param {String} className The model name that owns the key
@ -1430,11 +1420,19 @@ DataSource.prototype.defineForeignKey = function defineForeignKey(className, key
// quit if key already defined
if (this.getModelDefinition(className).rawProperties[key]) return;
var defaultType = Number;
if (foreignClassName) {
var foreignModel = this.getModelDefinition(foreignClassName);
var pkName = foreignModel && foreignModel.idName();
if (pkName) {
defaultType = foreignModel.properties[pkName].type;
}
}
if (this.connector.defineForeignKey) {
var cb = function (err, keyType) {
if (err) throw err;
// Add the foreign key property to the data source _models
this.defineProperty(className, key, {type: keyType || Number});
this.defineProperty(className, key, {type: keyType || defaultType});
}.bind(this);
switch (this.connector.defineForeignKey.length) {
case 4:
@ -1447,7 +1445,7 @@ DataSource.prototype.defineForeignKey = function defineForeignKey(className, key
}
} else {
// Add the foreign key property to the data source _models
this.defineProperty(className, key, {type: Number});
this.defineProperty(className, key, {type: defaultType});
}
};
@ -1662,7 +1660,6 @@ DataSource.prototype.ready = function(obj, args) {
return true;
};
/**
* Define a hidden property
* @param {Object} obj The property owner
@ -1694,7 +1691,6 @@ function defineReadonlyProp(obj, key, value) {
});
}
// Carry over a few properties/methods from the ModelBuilder as some tests use them
DataSource.Text = ModelBuilder.Text;
DataSource.JSON = ModelBuilder.JSON;

View File

@ -28,8 +28,10 @@ Hookable.afterDestroy = null;
// TODO: Evaluate https://github.com/bnoguchi/hooks-js/
Hookable.prototype.trigger = function trigger(actionName, work, data) {
var capitalizedName = capitalize(actionName);
var beforeHook = this.constructor["before" + capitalizedName] || this.constructor["pre" + capitalizedName];
var afterHook = this.constructor["after" + capitalizedName] || this.constructor["post" + capitalizedName];
var beforeHook = this.constructor["before" + capitalizedName]
|| this.constructor["pre" + capitalizedName];
var afterHook = this.constructor["after" + capitalizedName]
|| this.constructor["post" + capitalizedName];
if (actionName === 'validate') {
beforeHook = beforeHook || this.constructor.beforeValidation;
afterHook = afterHook || this.constructor.afterValidation;

View File

@ -87,7 +87,8 @@ Inclusion.include = function (objects, include, cb) {
if (!relation) {
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'));
}
}
@ -110,7 +111,8 @@ Inclusion.include = function (objects, include, cb) {
var inValues = [];
for (var j = 0; j < keyVals[relation.keyFrom].length; j++) {
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]);
}
}
@ -145,7 +147,8 @@ Inclusion.include = function (objects, include, cb) {
if (!objectsFrom[j].__cachedRelations) {
objectsFrom[j].__cachedRelations = {};
}
objectsFrom[j].__cachedRelations[relationName] = relation.multiple ? [] : null;
objectsFrom[j].__cachedRelations[relationName] =
relation.multiple ? [] : null;
}
}
cb(err, objsIncluded);
@ -153,7 +156,6 @@ Inclusion.include = function (objects, include, cb) {
};
}
return null;
}
}

View File

@ -14,7 +14,8 @@ exports.inherits = function (newClass, baseClass, options) {
if (options.staticProperties) {
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);
Object.defineProperty(newClass, classProp, pd);
}
@ -22,7 +23,6 @@ exports.inherits = function (newClass, baseClass, options) {
}
};
/**
* Mix in the a class into the new class
* @param newClass The target class to receive the mixin
@ -57,9 +57,11 @@ exports.mixin = function (newClass, mixinClass, options) {
if (options.staticProperties) {
var staticProxies = [];
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);
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);
}
Object.defineProperty(newClass, classProp, pd);

View File

@ -1,4 +1,3 @@
module.exports = List;
/**

View File

@ -109,7 +109,8 @@ ModelBuilder.prototype.getModelDefinition = function(name) {
ModelBuilder.prototype.define = function defineClass(className, properties, settings, parent) {
var modelBuilder = this;
var args = slice.call(arguments);
var pluralName = settings && settings.plural;
var pluralName = (settings && settings.plural) ||
inflection.pluralize(className);
if (!className) {
throw new Error('Class name required');
@ -186,8 +187,9 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett
// Add metadata to the ModelClass
hiddenProperty(ModelClass, 'modelBuilder', modelBuilder);
hiddenProperty(ModelClass, 'dataSource', modelBuilder); // Keep for back-compatibility
hiddenProperty(ModelClass, 'pluralModelName', pluralName || inflection.pluralize(className));
hiddenProperty(ModelClass, 'pluralModelName', pluralName);
hiddenProperty(ModelClass, 'relations', {});
hiddenProperty(ModelClass, 'http', { path: '/' + pluralName });
// inherit ModelBaseClass static methods
for (var i in ModelBaseClass) {
@ -461,7 +463,6 @@ ModelBuilder.prototype.extendModel = function (model, props) {
});
};
ModelBuilder.prototype.copyModel = function copyModel(Master) {
var modelBuilder = this;
var className = Master.modelName;
@ -491,7 +492,6 @@ ModelBuilder.prototype.copyModel = function copyModel(Master) {
return Slave;
};
/*!
* Define hidden property
*/

View File

@ -49,7 +49,6 @@ util.inherits(ModelDefinition, EventEmitter);
// Set up types
require('./types')(ModelDefinition);
/**
* Return table name for specified `modelName`
* @param {String} connectorType The connector type, such as 'oracle' or 'mongodb'
@ -165,7 +164,8 @@ ModelDefinition.prototype.idName = function() {
var id = this.ids()[0];
if (this.properties.id && this.properties.id.id) {
return 'id';
} else {}
} else {
}
return id && id.name;
};
@ -253,7 +253,6 @@ ModelDefinition.prototype.defineProperty = function (propertyName, propertyDefin
this.build(true);
};
function isModelClass(cls) {
if (!cls) {
return false;

View File

@ -68,7 +68,8 @@ Relation.hasMany = function hasMany(anotherClass, params) {
data = {};
}
if ('function' !== typeof done) {
done = function() {};
done = function () {
};
}
var self = this;
anotherClass.create(data, function (err, ac) {

View File

@ -34,7 +34,6 @@ BaseSQL.prototype.queryOne = function (sql, callback) {
});
};
/**
* Get the table name for a given model
* @param {String} model The model name
@ -96,7 +95,8 @@ BaseSQL.prototype.propertyName = function (model, column) {
* @returns {String} The column name
*/
BaseSQL.prototype.idColumn = function (model) {
var name = this.getDataSource(model).idColumnName(model);;
var name = this.getDataSource(model).idColumnName(model);
;
var dbName = this.dbName;
if (typeof dbName === 'function') {
name = dbName(name);
@ -155,7 +155,6 @@ BaseSQL.prototype.save = function (model, data, callback) {
});
};
/**
* Check if a model instance exists for the given id value
* @param {String} model The model name

View File

@ -58,4 +58,4 @@ module.exports = function (Types) {
Types.registerType(Array);
Types.registerType(GeoPoint);
Types.registerType(Object);
}
};

View File

@ -11,7 +11,9 @@ function safeRequire(module) {
try {
return require(module);
} 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);
}
}
@ -89,7 +91,8 @@ function removeUndefined(query) {
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.update(x, true); // Stop navigating into this object
return x;

View File

@ -1,6 +1,6 @@
{
"name": "loopback-datasource-juggler",
"version": "1.2.12",
"version": "1.2.13",
"description": "LoopBack DataSoure Juggler",
"keywords": [
"StrongLoop",

View File

@ -18,7 +18,6 @@ describe('basic-querying', function() {
});
describe('findById', function () {
before(function (done) {
@ -311,8 +310,6 @@ describe('basic-querying', function() {
});
});
function seed(done) {
@ -323,7 +320,8 @@ function seed(done) {
email: 'john@b3atl3s.co.uk',
role: 'lead',
order: 2
}, {
},
{
name: 'Paul McCartney',
email: 'paul@b3atl3s.co.uk',
role: 'lead',

View File

@ -1,4 +1,3 @@
var Schema = require('../index').Schema;
var Text = Schema.Text;
@ -72,6 +71,7 @@ function clearAndCreate(model, data, callback) {
});
var itemIndex = 0;
function nextItem(err, lastItem) {
if (lastItem !== null) {
createdItems.push(lastItem);
@ -125,13 +125,17 @@ function testOrm(dataSource) {
title: { type: String, length: 255, index: true },
subject: { type: String },
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 },
likes: [],
related: [RelatedPost]
}, {table: 'posts'});
function RelatedPost() { }
function RelatedPost() {
}
RelatedPost.prototype.someMethod = function () {
return this.parent;
};
@ -417,7 +421,6 @@ function testOrm(dataSource) {
test.done();
});
it('should handle hasMany relationship', function (test) {
User.create(function (err, u) {
if (err) return console.log(err);
@ -588,12 +591,14 @@ function testOrm(dataSource) {
});
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 M', subject: "C" },
{ title: 'Title A', subject: "A" },
{ title: 'Title B', subject: "A" },
{ title: 'Title C', subject: "D" }];
{ title: 'Title C', subject: "D" }
];
var isRedis = Post.dataSource.name === 'redis';
var dates = isRedis ? [ 5, 9, 0, 17, 10, 9 ] : [
new Date(1000 * 5),
@ -608,6 +613,7 @@ function testOrm(dataSource) {
});
var i = 0, tests = 0;
function done(err, obj) {
if (++i === titles.length) {
doFilterAndSortTest();
@ -713,6 +719,7 @@ function testOrm(dataSource) {
}
var fin = 0;
function finished() {
if (++fin === tests) {
test.done();
@ -790,7 +797,6 @@ function testOrm(dataSource) {
// }
// });
// if (
// dataSource.name === 'mysql' ||
// dataSource.name === 'postgres'
@ -884,6 +890,7 @@ function testOrm(dataSource) {
});
});
var tests = 2;
function done() {
process.nextTick(function () {
if (--wait === 0) {

View File

@ -277,17 +277,49 @@ describe('hooks', function() {
describe('lifecycle', function () {
var life = [], user;
before(function (done) {
User.beforeSave = function(d){life.push('beforeSave'); d();};
User.beforeCreate = function(d){life.push('beforeCreate'); d();};
User.beforeUpdate = function(d){life.push('beforeUpdate'); d();};
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.beforeSave = function (d) {
life.push('beforeSave');
d();
};
User.beforeCreate = function (d) {
life.push('beforeCreate');
d();
};
User.beforeUpdate = function (d) {
life.push('beforeUpdate');
d();
};
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;
life = [];

View File

@ -197,6 +197,7 @@ function clearAndCreate(model, data, callback) {
});
var itemIndex = 0;
function nextItem(err, lastItem) {
if (lastItem !== null) {
createdItems.push(lastItem);

View File

@ -98,7 +98,6 @@ describe('ModelBuilder define model', function () {
done(null, User);
});
it('should be able to define nesting models', function (done) {
var modelBuilder = new ModelBuilder();
@ -116,10 +115,12 @@ describe('ModelBuilder define model', function () {
zipCode: String,
country: String
},
emails: [{
emails: [
{
label: String,
email: String
}],
}
],
friends: [String]
});
@ -134,7 +135,9 @@ describe('ModelBuilder define model', function () {
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: ['Mary', 'John']
});
@ -189,10 +192,8 @@ describe('ModelBuilder define model', function () {
done(null, User);
});
});
describe('DataSource define model', function () {
it('should be able to define plain models', function () {
var ds = new DataSource('memory');
@ -401,7 +402,6 @@ describe('DataSource define model', function () {
done(null, User);
});
it('should change the property value for save if strict=false', function (done) {
var ds = new DataSource('memory');// define models
var Post = ds.define('Post');
@ -424,8 +424,10 @@ describe('Load models with base', function () {
var User = ds.define('User', {name: String});
User.staticMethod = function staticMethod() {};
User.prototype.instanceMethod = function instanceMethod() {};
User.staticMethod = function staticMethod() {
};
User.prototype.instanceMethod = function instanceMethod() {
};
var Customer = ds.define('Customer', {vip: Boolean}, {base: 'User'});
@ -433,7 +435,6 @@ describe('Load models with base', function () {
assert(Customer.staticMethod === User.staticMethod);
assert(Customer.prototype.instanceMethod === User.prototype.instanceMethod);
try {
var Customer1 = ds.define('Customer1', {vip: Boolean}, {base: 'User1'});
} catch (e) {
@ -510,6 +511,19 @@ describe('Load models with relations', function () {
done();
});
it('should set up foreign key with the correct type', function (done) {
var ds = new DataSource('memory');
var User = ds.define('User', {name: String, id: {type: String, id: true}});
var Post = ds.define('Post', {content: String}, {relations: {user: {type: 'belongsTo', model: 'User'}}});
var fk = Post.definition.properties['userId'];
assert(fk, 'The foreign key should be added');
assert(fk.type === String, 'The foreign key should be the same type as primary key');
assert(Post.relations['user'], 'User relation should be set');
done();
});
it('should set up hasMany and belongsTo relations', function (done) {
var ds = new DataSource('memory');
@ -614,7 +628,6 @@ describe('Load models with relations', function () {
done();
});
});
describe('DataAccessObject', function () {
@ -728,7 +741,6 @@ describe('Load models from json', function () {
var path = require('path'),
fs = require('fs');
/**
* Load LDL schemas from a json doc
* @param schemaFile The dataSource json file
@ -914,7 +926,6 @@ describe('DataSource constructor', function(){
});
});
describe('Injected methods from connectors', function () {
it('are not shared across models for remote methods', function () {
var ds = new DataSource('memory');
@ -952,7 +963,6 @@ describe('Injected methods from connectors', function(){
});
describe('ModelBuilder options.models', function () {
it('should inject model classes from models', function () {
var builder = new ModelBuilder();

View File

@ -89,7 +89,11 @@ describe('manipulation', function() {
});
it('should create batch of objects', function (done) {
var batch = [{name: 'Shaltay'}, {name: 'Boltay'}, {}];
var batch = [
{name: 'Shaltay'},
{name: 'Boltay'},
{}
];
Person.create(batch,function (e, ps) {
should.not.exist(e);
should.exist(ps);

View File

@ -29,7 +29,6 @@ describe('ModelDefinition class', function () {
assert.equal(User.properties.joinedAt.type, Date);
assert.equal(User.properties.age.type, Number);
var json = User.toJSON();
assert.equal(json.name, "User");
assert.equal(json.properties.name.type, "String");
@ -40,7 +39,6 @@ describe('ModelDefinition class', 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);
done();
});
it('should be able to define nesting models', function (done) {
var modelBuilder = new ModelBuilder();
@ -112,7 +108,6 @@ describe('ModelDefinition class', function () {
});
it('should be able to define referencing models', function (done) {
var modelBuilder = new ModelBuilder();
@ -140,7 +135,6 @@ describe('ModelDefinition class', function () {
assert.equal(User.properties.age.type, Number);
assert.equal(User.properties.address.type, Address);
var json = User.toJSON();
assert.equal(json.name, "User");
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.address.type, Address);
var json = User.toJSON();
assert.equal(json.name, "User");
assert.equal(json.properties.name.type, "String");

View File

@ -15,14 +15,12 @@ schemas =
url: 'http://localhost:5984/nano-test'
testOrm = (dataSource) ->
User = Post = 'unknown'
maxUsers = 100
maxPosts = 50000
users = []
it 'should define simple', (test) ->
User = dataSource.define 'User', {
name: String,
bio: Text,
@ -51,7 +49,8 @@ testOrm = (dataSource) ->
it 'should create bunch of data', (test) ->
wait = maxPosts
done = -> test.done() if --wait == 0
done = ->
test.done() if --wait == 0
rnd = (title) ->
{
userId: users[Math.floor(Math.random() * maxUsers)].id
@ -61,11 +60,13 @@ testOrm = (dataSource) ->
it 'do some queries using foreign keys', (test) ->
wait = 4
done = -> test.done() if --wait == 0
done = ->
test.done() if --wait == 0
ts = Date.now()
query = (num) ->
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()
query num for num in [0..4]

View File

@ -4,11 +4,9 @@ var fieldsToArray = utils.fieldsToArray;
var removeUndefined = utils.removeUndefined;
var mergeSettings = utils.mergeSettings;
describe('util.fieldsToArray', function () {
it('Turn objects and strings into an array of fields to include when finding models', function () {
function sample(fields) {
var properties = ['foo', 'bar', 'bat', 'baz'];
return {