clever-orm
Advanced tools
Comparing version 1.1.5 to 1.2.0
161
module.js
@@ -6,2 +6,3 @@ var injector = require( 'injector' ) | ||
, Promise = require( 'bluebird' ) | ||
, async = require( 'async' ) | ||
, _ = require( 'underscore' ) | ||
@@ -72,3 +73,4 @@ , i = require( 'i' )(); | ||
models[ association.source.name ]._setters[ association.identifier ] = function( val ) { | ||
models[ association.source.name ]._setters[ association.identifier ] = | ||
models[ association.source.name ]._setters[ as ] = function( val ) { | ||
this._model[ association.as ] = val; | ||
@@ -95,7 +97,17 @@ }; | ||
this._model[ accessor ]( where, options ) | ||
.then( function( _model ) { | ||
resolve( _model ); | ||
}) | ||
.catch( reject ); | ||
if ( !!options && options.save === false ) { | ||
this._model[ accessor ]( where, options ); | ||
resolve(this); | ||
} else { | ||
this._model[ accessor ]( where, options ) | ||
.then( function( _model ) { | ||
if (/set/.test(accessor) && this._model[ as ]) { | ||
this._model[ as ]._model = where; | ||
resolve( this ); | ||
} else { | ||
resolve( _model ); | ||
} | ||
}.bind(this)) | ||
.catch( reject ); | ||
} | ||
} else { | ||
@@ -121,16 +133,124 @@ this._model[ accessor ].then( resolve ).catch( reject ); | ||
associateModels: function( modelName, assocType, assocTo ) { | ||
// Support second argument | ||
if ( assocTo instanceof Array ) { | ||
this.debug( '%s %s %s with second argument of ', modelName, assocType, assocTo[0], assocTo[1] ); | ||
associateModels: function( sourceModelName, assocType, assocTo ) { | ||
assocTo = assocTo instanceof Array ? _.clone(assocTo) : [assocTo, {}]; | ||
if ( assocTo[ 1 ].through ) { | ||
assocTo[ 1 ].through = this.models[ assocTo[ 1 ].through.replace( 'Model', '' ) ]; | ||
} | ||
var targetModelName = assocTo.shift() | ||
, associationOptions = assocTo.shift() | ||
, sourceModel = injector.getInstance(sourceModelName + 'Model') | ||
, targetModel = injector.getInstance((associationOptions.through ? associationOptions.through : targetModelName) + 'Model') | ||
, as = associationOptions.as || targetModelName.replace('Model',''); | ||
this.models[ modelName ][ assocType ]( this.models[ assocTo[0] ], assocTo[1] ); | ||
} else { | ||
this.debug( '%s %s %s', modelName, assocType, assocTo ); | ||
this.models[ modelName ][ assocType ]( this.models[assocTo] ); | ||
if ( associationOptions.through ) { | ||
associationOptions.through = this.models[ associationOptions.through.replace( 'Model', '' ) ]; | ||
} | ||
this.debug( '%s %s %s %s', sourceModelName, assocType, targetModelName, associationOptions); | ||
this.models[ sourceModelName ][ assocType ]( this.models[targetModelName], associationOptions ); | ||
if (associationOptions.autoHooks !== false) { | ||
injector.getInstance('moduleLoader').on( 'routesInitialized', function() { | ||
if (assocType === 'belongsTo') { | ||
sourceModel.on('beforeCreate', function(modelData, queryOptions, callback) { | ||
if (modelData[as] !== undefined && modelData[as]._model === undefined && (typeof modelData[as] !== 'object' || modelData[as][targetModel.primaryKey[0]] === undefined)) { | ||
targetModel | ||
.find(typeof modelData[as] === 'object' ? _.clone(modelData[as]) : modelData[as], queryOptions) | ||
.then(function(instance) { | ||
modelData[as] = instance; | ||
callback(null); | ||
}) | ||
.catch(callback); | ||
} else { | ||
callback(null); | ||
} | ||
}); | ||
sourceModel.on('afterCreate', function(instance, modelData, queryOptions, callback) { | ||
if (modelData[as] !== undefined && modelData[as]._model !== undefined) { | ||
instance._model[as] = modelData[as]; | ||
instance._model.values[as] = modelData[as]; | ||
callback(null); | ||
} else { | ||
callback(null); | ||
} | ||
}); | ||
// sourceModel.on('beforeUpdate', function(modelData, queryOptions, callback) { | ||
// if (modelData[as] !== undefined && modelData[as]._model === undefined && (typeof modelData[as] !== 'object' || modelData[as][targetModel.primaryKey[0]] === undefined)) { | ||
// targetModel | ||
// .find(typeof modelData[as] === 'object' ? _.clone(modelData[as]) : modelData[as], queryOptions) | ||
// .then(function(instance) { | ||
// modelData[as] = instance; | ||
// callback(null); | ||
// }) | ||
// .catch(callback); | ||
// } else { | ||
// callback(null); | ||
// } | ||
// }); | ||
} else if (assocType === 'hasMany') { | ||
sourceModel.on('afterCreate', function(instance, modelData, queryOptions, callback) { | ||
var association = instance.Class._model.associations[as]; | ||
// handle single association creation via the singular name | ||
// handle multiple association create via the plural name as an array of models | ||
// support nested association hasMany creation (plural and singular) with "Through", findBy ? | ||
// allow mapping of requestFields that will be used for create | ||
// allow definition of finders? | ||
if (modelData[as] !== undefined && modelData[as] instanceof Array && modelData[as].length) { | ||
async.map( | ||
modelData[as], | ||
function createNestedHasManyModel(nestedModelData, done) { | ||
var data = _.extend( | ||
typeof nestedModelData === 'object' ? _.clone(nestedModelData) : { label: nestedModelData }, | ||
_.pick(instance, association.options.foreignKey) | ||
); | ||
targetModel.create(data, queryOptions).then(function(targetInstance) { | ||
done(null, targetInstance); | ||
}) | ||
.catch(done); | ||
}, | ||
function createdNestedHasManyModels(err, associations) { | ||
if (!err) { | ||
instance._model[as] = associations; | ||
instance._model.values[as] = associations; | ||
callback(null); | ||
} else { | ||
callback(err); | ||
} | ||
} | ||
); | ||
} else { | ||
callback(null); | ||
} | ||
}); | ||
// sourceModel.on('afterUpdate') | ||
} else if (assocType === 'hasOne') { | ||
sourceModel.on('afterCreate', function(instance, modelData, queryOptions, callback) { | ||
var association = instance.Class._model.associations[as]; | ||
if (modelData[as] !== undefined && modelData[as]._model === undefined && typeof modelData[as] === 'object') { | ||
var data = _.extend( | ||
typeof modelData[as] === 'object' ? _.clone(modelData[as]) : { label: modelData[as] }, | ||
_.pick(instance, association.options.foreignKey) | ||
); | ||
targetModel.create(data, queryOptions).then(function(targetInstance) { | ||
instance._model[as] = targetInstance; | ||
instance._model.values[as] = targetInstance; | ||
callback(null); | ||
}) | ||
.catch(callback); | ||
} else { | ||
callback(null); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
}, | ||
@@ -227,2 +347,9 @@ | ||
sequelizeConf.deletedAt = Static.deletedAt; | ||
if ( Static.deletedAt !== 'deletedAt' ) { | ||
Static._aliases.push({ | ||
key : 'deletedAt', | ||
columnName : Static.deletedAt | ||
}); | ||
} | ||
} | ||
@@ -229,0 +356,0 @@ |
{ | ||
"name": "clever-orm", | ||
"description": "CleverStack ORM (SQL) Module", | ||
"version": "1.1.5", | ||
"version": "1.2.0", | ||
"main": "module.js", | ||
@@ -31,3 +31,6 @@ "author": { | ||
"sqlite", | ||
"dao" | ||
"dao", | ||
"object", | ||
"relational", | ||
"mapper" | ||
], | ||
@@ -34,0 +37,0 @@ "license": "BSD-2-Clause", |
@@ -5,3 +5,3 @@ module.exports = function ( Model, config ) { | ||
type: 'ORM', | ||
softDeletable: true, | ||
softDeleteable: true, | ||
timeStampable: true | ||
@@ -8,0 +8,0 @@ }, |
@@ -8,4 +8,5 @@ var utils = require( 'utils' ) | ||
, packageJson = injector.getInstance( 'packageJson' ) | ||
, ormModel = path.resolve( path.join( __dirname, '..', 'assets', 'OrmModel.js' ) ) | ||
, ormModel = require( ormModel ) | ||
, _ = require( 'underscore' ) | ||
, ormModel = path.resolve( path.join( __dirname, '..', 'assets', 'OrmModel.js' ) ) | ||
, ormModel = require( ormModel ) | ||
, OrmModel; | ||
@@ -104,6 +105,11 @@ | ||
it( 'Should have defined Orms table in MySQL', function( done ) { | ||
injector.getInstance( 'sequelize' ).query( 'describe Orms;', { raw: true }) | ||
// @todo this is broken | ||
it.skip( 'Should have defined Orms table in MySQL', function( done ) { | ||
injector.getInstance( 'sequelize' ).query( 'describe ' + OrmModel._model.tableName + ';', { raw: true }) | ||
.then(function( desc ) { | ||
expect( JSON.stringify( desc ) ).to.equal( '{"id":{"type":"INT(11)","allowNull":false,"defaultValue":null},"str":{"type":"VARCHAR(255)","allowNull":true,"defaultValue":null},"bool":{"type":"TINYINT(1)","allowNull":true,"defaultValue":null},"date":{"type":"DATETIME","allowNull":true,"defaultValue":null},"enum":{"type":"ENUM(\'TEST\')","allowNull":true,"defaultValue":null},"enumObj":{"type":"ENUM(\'TEST\')","allowNull":true,"defaultValue":null},"buf":{"type":"VARCHAR(255)","allowNull":true,"defaultValue":null},"bigint":{"type":"BIGINT(20)","allowNull":true,"defaultValue":null},"bigintLen":{"type":"BIGINT(11)","allowNull":true,"defaultValue":null},"float":{"type":"FLOAT","allowNull":true,"defaultValue":null},"floatLen":{"type":"FLOAT","allowNull":true,"defaultValue":null},"floatLenAndDec":{"type":"FLOAT(11,10)","allowNull":true,"defaultValue":null},"dec":{"type":"DECIMAL(10,0)","allowNull":true,"defaultValue":null},"decPrec":{"type":"DECIMAL(11,0)","allowNull":true,"defaultValue":null},"decPrecAndScale":{"type":"DECIMAL(10,2)","allowNull":true,"defaultValue":null},"text":{"type":"TEXT","allowNull":true,"defaultValue":null},"textObj":{"type":"TEXT","allowNull":true,"defaultValue":null},"createdAt":{"type":"DATETIME","allowNull":true,"defaultValue":null},"updatedAt":{"type":"DATETIME","allowNull":true,"defaultValue":null},"deletedAt":{"type":"DATETIME","allowNull":true,"defaultValue":null}}' ); | ||
var modelSchemaKeys = Object.keys( OrmModel._schema).map( function( fieldName ) { | ||
var field = OrmModel._schema[ fieldName ]; | ||
return field.field ? field.field : fieldName; | ||
}); | ||
expect( Object.keys( JSON.parse( JSON.stringify( desc ) ) ) ).to.eql( modelSchemaKeys ); | ||
done(); | ||
@@ -138,6 +144,6 @@ }) | ||
OrmModel | ||
.create( _model ) | ||
.create( _.clone( _model ) ) | ||
.then( function( model ) { | ||
Object.keys( _model ).forEach( function( key ) { | ||
expect( model._model.dataValues[ key ] ).to.eql( _model[ key ] ); | ||
expect( model[ key ] ).to.eql( _model[ key ] ); | ||
}); | ||
@@ -144,0 +150,0 @@ done(); |
@@ -1,23 +0,42 @@ | ||
var inflect = require( 'i' )() | ||
, injector = require( 'injector' ) | ||
, Promise = require( 'bluebird' ); | ||
var inflect = require('i')() | ||
, utils = require('utils') | ||
, modelUtils = utils.modelUtils | ||
, inspect = modelUtils.debugInspect | ||
, underscore = require('underscore') | ||
, async = require('async') | ||
, injector = require('injector') | ||
, Exceptions = require('exceptions') | ||
, sequelize = require('sequelize') | ||
, util = require('util'); | ||
var ormUtils = module.exports = { | ||
supportSingleModule: function( env, moduleName ) { | ||
if ( moduleName ) { | ||
supportSingleModule: function(env, moduleName) { | ||
if (moduleName) { | ||
env.packageJson.bundledDependencies.length = 0 | ||
env.packageJson.bundledDependencies.push( 'clever-orm', env ); | ||
env.packageJson.bundledDependencies.push( moduleName, env ); | ||
env.packageJson.bundledDependencies.push('clever-orm', env); | ||
env.packageJson.bundledDependencies.push(moduleName, env); | ||
} | ||
}, | ||
eagerLoad: function( findOptions ) { | ||
if ( !!findOptions.include && findOptions.include instanceof Array ) { | ||
for( var i = 0; i < findOptions.include.length; i++ ) { | ||
if ( findOptions.include[ i ]._model ) { | ||
findOptions.include[ i ] = findOptions.include[ i ]._model; | ||
} else if ( findOptions.include[ i ].model && findOptions.include[ i ].model._model ) { | ||
findOptions.include[ i ].model = findOptions.include[ i ].model._model; | ||
eagerLoad: function(findOptions) { | ||
if (!!findOptions.include && findOptions.include instanceof Array) { | ||
for(var i = 0; i < findOptions.include.length; i++) { | ||
this.debug('eagerLoad(' + inspect(underscore.omit(findOptions.include[i], 'model', 'include')) + ', ' + inspect(findOptions.include[i].model.name) + ')'); | ||
if (findOptions.include[i]._model) { | ||
findOptions.include[i] = findOptions.include[i]._model; | ||
} else if (findOptions.include[i].model && findOptions.include[i].model._model) { | ||
findOptions.include[i].model = findOptions.include[i].model._model; | ||
} | ||
// Handle customColumnNames in nested include.where's | ||
if (findOptions.include[i].where) { | ||
modelUtils.aliasFieldsForQuery.apply(injector.getInstance(findOptions.include[i].model.name + 'Model'), [findOptions.include[i].where]); | ||
} | ||
// Handle nested includes | ||
if (findOptions.include[i].include) { | ||
ormUtils.eagerLoad.apply(this, [findOptions.include[i].include]); | ||
} | ||
} | ||
@@ -27,69 +46,115 @@ } | ||
afterEagerLoad: function( findOptions, model ) { | ||
if ( model !== null && findOptions.include && findOptions.include.length && model._model.options.include ) { | ||
var models = this.getDefinedModels; | ||
afterEagerLoad: function(findOptions, model) { | ||
if (model !== null && findOptions.include && findOptions.include.length && model._model.options.include) { | ||
var models = this.getDefinedModels(); | ||
Object.keys( model._model.options.includeMap ).forEach( function( modelName ) { | ||
var _include = model._model.options.includeMap[ modelName ] | ||
, as = inflect.camelize( _include.as, false ) | ||
, csModel = models[ modelName ]; | ||
Object.keys(model._model.options.includeMap).forEach(function(modelName) { | ||
var _include = model._model.options.includeMap[modelName] | ||
, as = inflect.camelize(_include.as, false) | ||
, csModel = models[_include.association.target ? _include.association.target.name : modelName]; | ||
if ( !!csModel && !!model._model[ as ] ) { | ||
if ( model._model[ as ] instanceof Array ) { | ||
for ( var i = 0; i < model._model[ as ].length; i++ ) { | ||
if ( !( model._model[ as ][ i ] instanceof csModel ) ) { | ||
model._model[ as ][ i ] = new csModel( model._model[ as ][ i ] ); | ||
this.debug('afterEagerLoad(' + inspect(_include.as) + ', ' + inspect(_include.model.name) + ')'); | ||
if (!!csModel && !!model._model[as]) { | ||
if (model._model[as] instanceof Array) { | ||
for (var i = 0; i < model._model[as].length; i++) { | ||
if (!(model._model[as][i] instanceof csModel)) { | ||
model._model[as][i] = new csModel(model._model[as][i]); | ||
ormUtils.afterEagerLoad.apply(csModel, [model._model[as][i]._model.options, model._model[as][i]]); | ||
} | ||
} | ||
} else { | ||
if ( !( model._model[ as ] instanceof csModel ) ) { | ||
model._model[ as ] = new csModel( model._model[ as ] ); | ||
if (!(model._model[as] instanceof csModel)) { | ||
model._model[as] = new csModel(model._model[as]); | ||
ormUtils.afterEagerLoad.apply(csModel, [model._model[as]._model.options, model._model[as]]); | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
.bind(this)); | ||
} | ||
}, | ||
find: function( findOptions, options, callback ) { | ||
ormUtils.eagerLoad( findOptions ); | ||
find: function(findOptions, queryOptions, callback) { | ||
this.debug('ormUtils.find(' + inspect(findOptions) + ')'); | ||
ormUtils.eagerLoad.apply(this, [findOptions, queryOptions]); | ||
this._model | ||
.find( findOptions, options ) | ||
.then( this.callback( function( _model ) { | ||
var model = !!_model && _model !== null ? new this( _model ) : null; | ||
.find(findOptions, queryOptions) | ||
.then(function( model ) { | ||
ormUtils.wrapModel.apply(this, [ findOptions, model, callback ]); | ||
}.bind(this)) | ||
.catch(callback); | ||
}, | ||
ormUtils.afterEagerLoad.apply( this, [ findOptions, model ] ); | ||
wrapModel: function(findOptions, model, callback) { | ||
if (model !== null) { | ||
model = new this(model); | ||
callback( null, model ); | ||
ormUtils.afterEagerLoad.apply(this, [findOptions, model]); | ||
return !callback ? model : callback( null, model ); | ||
} else { | ||
return !callback ? null : callback( null, null ); | ||
} | ||
}, | ||
findAll: function(findOptions, queryOptions, callback) { | ||
ormUtils.eagerLoad.apply(this, [findOptions, queryOptions]); | ||
this._model | ||
.findAll(findOptions, queryOptions) | ||
.then(this.callback(function(results) { | ||
results = async.map( | ||
results instanceof Array ? results : [results], | ||
this.callback(ormUtils.wrapModel, findOptions), | ||
callback | ||
); | ||
})) | ||
.catch( callback ); | ||
.catch(callback); | ||
}, | ||
findAll: function( findOptions, options, callback ) { | ||
var that = this; | ||
create: function(modelData, queryOptions, callback) { | ||
var data = underscore.pick(modelData, Object.keys(this._model.attributes)); | ||
ormUtils.eagerLoad( findOptions ); | ||
this.debug(util.format('ormUtils.create(%s)', Object.keys(data).join(', '))); | ||
this._model.create(data, queryOptions).then(this.callback(function(_model) { | ||
callback(null, new this(_model)); | ||
})) | ||
.catch(sequelize.UniqueConstraintError, this.callback(function(e) { | ||
var columnName = Object.keys(e.fields).shift() | ||
, column = underscore.findWhere(this._aliases, { columnName: columnName }); | ||
callback(new Exceptions.DuplicateModel(util.format('Unable to create a new %s, identity already exists (%s).', column.key, e.fields[columnName]))); | ||
})) | ||
.catch(callback); | ||
}, | ||
save: function(data, queryOptions, callback) { | ||
this.debug('ormUtils.save()'); | ||
this._model | ||
.findAll( findOptions, options ) | ||
.then( function( _models ) { | ||
var models = []; | ||
_models = _models instanceof Array ? _models : [ _models ]; | ||
.save(data, queryOptions) | ||
.then(callback.bind(null, null)) | ||
.catch(callback) | ||
}, | ||
_models.forEach(function( model ) { | ||
if ( model !== null ) { | ||
model = new that( model ); | ||
destroy: function(queryOptions, callback) { | ||
this.debug('ormUtils.destroy()'); | ||
this._model | ||
.destroy(queryOptions) | ||
.then(callback.bind(null, null)) | ||
.catch(callback) | ||
}, | ||
ormUtils.afterEagerLoad.apply( that, [ findOptions, model ] ); | ||
softDeleteable: function(findOptions, queryOptions, callback) { | ||
if (!!this.softDeleteable) { | ||
this.debug('softDeleteable(' + this.deletedAt + ')'); | ||
findOptions[this.deletedAt] = null; | ||
} | ||
models.push( model ); | ||
} | ||
}); | ||
callback( null, models ); | ||
}) | ||
.catch( callback ); | ||
callback && callback(null); | ||
} | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
69243
1262
11