Skip to content

Commit

Permalink
Merge pull request #9 from CleverStack/feature/fcc-models
Browse files Browse the repository at this point in the history
FCC Models Implementation
  • Loading branch information
pilsy committed Jun 7, 2014
2 parents 03c55bf + aedd6bc commit bcfbccb
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 41 deletions.
8 changes: 8 additions & 0 deletions bin/rebase.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ var fs = require( 'fs' )
? process.argv[ 2 ]
: false;

// Add some classes for simplicity
var classes = require( 'classes' );
injector.instance( 'Class', classes.Class );
injector.instance( 'Model', classes.Model );
injector.instance( 'Service', classes.Service );
injector.instance( 'Controller', classes.Controller );
injector.instance( 'Module', classes.Module );

console.log('Forcing Database to be created! (Note: All your data will disapear!)');

// Load all the modules
Expand Down
14 changes: 11 additions & 3 deletions bin/seedModels.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ var fs = require( 'fs' )
var env = utils.bootstrapEnv()
, config = env.config;

// Add some classes for simplicity
var classes = require( 'classes' );
injector.instance( 'Class', classes.Class );
injector.instance( 'Model', classes.Model );
injector.instance( 'Service', classes.Service );
injector.instance( 'Controller', classes.Controller );
injector.instance( 'Module', classes.Module );

// Load all the modules
if ( moduleName ) {
env.moduleLoader.loadModule( 'clever-orm', env );
Expand All @@ -32,7 +40,7 @@ Object.keys(seedData).forEach(function( modelName ) {
async.forEachSeries(
Object.keys(seedData),
function forEachModelType( modelName, cb ) {
var ModelType = models.orm[modelName]
var ModelType = models[ modelName.replace( 'Model', '' ) ]
, Models = seedData[modelName];

if ( !ModelType || !Models ) {
Expand All @@ -45,7 +53,7 @@ async.forEachSeries(
var assocs = data.associations;
delete data.associations;

ModelType.create(data).success(function( model ) {
ModelType.create(data).then(function( model ) {
data.associations = assocs;

console.log('Created ' + modelName);
Expand Down Expand Up @@ -100,7 +108,7 @@ async.forEachSeries(
} else {
modelCb(null);
}
}).error(modelCb);
}).catch(modelCb);
},
function forEachModelComplete( err ) {
cb(err);
Expand Down
121 changes: 85 additions & 36 deletions module.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,38 @@
var Sequelize = require( 'sequelize' )
, debug = require( 'debug' )( 'ORM' )
, ModuleClass = require( 'classes' ).ModuleClass
, sequelize
, Module;
var mongoose = require( 'mongoose' )
, injector = require( 'injector' )
, Sequelize = require( 'sequelize' )
, Module = require( 'classes' ).Module;

Module = ModuleClass.extend({
models: null,
module.exports = Module.extend({

models: {},

sequelize: null,

preSetup: function() {
this.models = {};
},
this.debug( 'Opening database connection to ' + this.config.db.options.dialect + '...' );

preInit: function() {
debug( 'Opening connection to database' );

sequelize = new Sequelize(
this.sequelize = new Sequelize(
this.config.db.database,
this.config.db.username,
this.config.db.password,
this.config.db.options
);
},

preInit: function() {
this.debug( 'Adding Sequelize module and sequelize instance to the injector...' );

injector.instance( 'Sequelize', Sequelize );
injector.instance( 'DataTypes', Sequelize );
injector.instance( 'sequelize', sequelize );
injector.instance( 'sequelize', this.sequelize );
},

modulesLoaded: function() {
this.defineModelsAssociations();
},

defineModelsAssociations: function() {
debug( 'Defining model assocations' );
this.debug( 'Defining model assocations' );

Object.keys( this.config.modelAssociations ).forEach( this.proxy( function( modelName ) {
Object.keys( this.config.modelAssociations[ modelName ] ).forEach( this.proxy( 'defineModelAssociations', modelName ) );
Expand All @@ -50,32 +51,80 @@ Module = ModuleClass.extend({
associateModels: function( modelName, assocType, assocTo ) {
// Support second argument
if ( assocTo instanceof Array ) {
debug( '%s %s %s with second argument of ', modelName, assocType, assocTo[0], assocTo[1] );
this.debug( '%s %s %s with second argument of ', modelName, assocType, assocTo[0], assocTo[1] );
this.models[ modelName ][ assocType ]( this.models[ assocTo[0] ], assocTo[1] );
} else {
debug( '%s %s %s', modelName, assocType, assocTo );
this.debug( '%s %s %s', modelName, assocType, assocTo );
this.models[ modelName ][ assocType ]( this.models[assocTo] );
}
},

getModel: function( modelPath ) {
var modelName = modelPath.split( '/' ).pop().split( '.' ).shift();

if ( typeof this.models[ modelName ] === 'undefined' ) {
debug( [ 'Loading model', modelName, 'from', modelPath ].join( ' ' ) );

// Call on sequelizejs to load the model
this.models[ modelName ] = sequelize.import( modelPath );
parseModelSchema: function( Static, Proto ) {
var parseDebug = this.proxy(function( msg ) {
this.debug( Static._name + 'Model: ' + msg );
})
, sequelizeConf = {}
, fields = {};

// Set a flat for tracking
this.models[ modelName ].ORM = true;

// Add the model to the injector
injector.instance( 'ORM' + modelName, this.models[ modelName ] );
if ( this.models[ Static._name ] !== undefined ) {
parseDebug( 'Returning previously parsed and generated model...' );
return this.models[ Static._name ];
}

return this.models[ modelName ];
},
});

module.exports = new Module( 'clever-orm', injector );
parseDebug( 'Parsing schema for model...' );
Object.keys( Static._schema ).forEach(function( name ) {
var options = Static._schema[ name ]
, fieldDefinition = {};

// If a type has been specified outside of the object, handle that
if ( typeof options !== 'object' ) {
options = {
type: options
}
}

// Figure out the type mapping for sequelizejs
if ( options.type === undefined ) {
throw new Error( [ 'You must define the type of field that', '"' + name + '"', 'is on the', '"' + Static.name + '" model' ].join( ' ' ) );
} else if ( options.type === Number ) {
fieldDefinition.type = Sequelize.INTEGER;
} else if ( options.type === String ) {
fieldDefinition.type = Sequelize.STRING;
} else if ( options.type === Boolean ) {
fieldDefinition.type = Sequelize.BOOLEAN;
} else if ( options.type === Date ) {
fieldDefinition.type = Sequelize.DATE;
} else {
throw new Error( [ 'You must define a valid type for the field named', '"' + name + '"', 'on the', '"' + Static.name + '" model' ].join( ' ' ) );
}

// Handle options
[ 'allowNull', 'primaryKey', 'autoIncrement', 'unique', 'required', 'validate', 'default' ].forEach(function( optionName ) {
if ( options[ optionName ] !== undefined ) {
if ( optionName === 'primaryKey' ) {
Static.primaryKey = name;
}

fieldDefinition[ optionName === 'default' ? 'defaultValue' : optionName ] = options[ optionName ];
}
});

fields[ name ] = fieldDefinition;
});

parseDebug( 'Configuring static object for sequelize...' );
sequelizeConf.paranoid = Static.softDeletable;
sequelizeConf.timestamps = Static.timeStampable;

parseDebug( 'Setting sequelize as the _db (adapter) for the Model...' );
Static._db = this.sequelize;

parseDebug( 'Generating new sequelize model using computed schema...' );
var model = this.sequelize.define( Static._name, fields, sequelizeConf );

parseDebug( 'Caching completed native model...' );
this.models[ Static._name ] = model;

return model;
}
});
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "clever-orm",
"version": "0.0.16",
"version": "1.0.0",
"dependencies": {
"mysql": "2.0.0-rc2",
"sequelize": "^1.7.x"
Expand All @@ -11,7 +11,7 @@
"web": "http://www.clevertech.biz"
},
"collaborators": [
"Richard Gustin <richard@clevertech.biz>"
"Richard Gustin <richard.gustin86@gmail.com>"
],
"description": "Clevertech ORM (SQL) Module for CleverStack",
"keywords": [
Expand Down

0 comments on commit bcfbccb

Please sign in to comment.