不要怂,就是干,撸起袖子干!

Commit e170cd49 by Meg Sharkey

merged

2 parents 124920a6 751a6de3
......@@ -27,10 +27,72 @@ Also make sure to take a look at the examples in the repository. The website wil
I'm glad to get pull request if any functionality is missing or something is buggy. But _please_ ... run the tests before you send me the pull request.
## Tests ##
Now if you want to contribute but don't really know where to begin
don't worry, the steps below will guide you to have a sequelize
contributor's environment running in a couple minutes.
In order to run the tests, just do ```npm install```, which will install jasmine. Please add tests to your pull requests. This is how you start the tests:
### 1. Prepare the environment ###
node_modules/.bin/jasmine-node spec/
All the following steps consider you already have [npm](http://npmjs.org/) installed in your [node.js version 0.4.6 or higher](https://github.com/sdepold/sequelize/blob/master/package.json#L30)
Current build status on travis-ci: [![Build Status](https://secure.travis-ci.org/sdepold/sequelize.png)](http://travis-ci.org/sdepold/sequelize)
#### 1.1 MySQL and other external dependencies ####
Contributing to sequelize requires you to have
[MySQL](http://www.mysql.com/) up and running in your local
environment. The reason for that is that we have test cases that runs
against an actual MySQL server and make sure everything is always
working.
That is also one of the reasons your features must come with tests:
let's make sure sequelize will stay awesome as more features are added
as well as that fixed bugs will never come back.
Well, after installing **MySQL** you also need to create the sequelize test database:
```console
$ echo "CREATE DATABASE sequelize_test;" | mysql -uroot
```
**CLEVER NOTE:** your local MySQL install must be with username `root`
without password. If you want to customize that just hack in the
tests, but make sure to don't commit your credentials, we don't want
to expose your personal data in sequelize codebase ;)
**AND ONE LAST THING:** Sequelize also supports SQLite. So this should be working
on your machine as well :)
### 2. Install the dependencies ###
Just "cd" into sequelize directory and run `npm install`, see an example below:
```console
$ cd path/to/sequelize
$ npm install
```
### 3. Run the tests ###
In order to run the tests you got to run `jasmine-node` against the `spec` directory.
By the way, [there](https://github.com/sdepold/sequelize/tree/master/spec) is where
you will write new tests if that's the case.
All you need is to run `./node_modules/.bin/jasmine-node spec/`,
although this is kinda long and boring, so we configures a NPM task
and made that less laborious to you :)
```console
$ npm test
```
### 4. That's all ###
Just commit and send pull requests.
Happy hacking and thank you for contributing
# Build status
The automated tests we talk about just so much are running on
[Travis public CI](http://travis-ci.org), here is its status:
[![Build Status](https://secure.travis-ci.org/sdepold/sequelize.png)](http://travis-ci.org/sdepold/sequelize)
......@@ -80,7 +80,7 @@ if(program.migrate) {
, migrator = sequelize.getMigrator(migratorOptions)
if(program.undo) {
sequelize.migrator.findOrCreateSequelizeMetaModel().success(function(Meta) {
sequelize.migrator.findOrCreateSequelizeMetaDAO().success(function(Meta) {
Meta.find({ order: 'id DESC' }).success(function(meta) {
if(meta) {
migrator = sequelize.getMigrator(_.extend(migratorOptions, meta), true)
......
# v1.3.7 #
- [BUG] fixed issue where multiple belongsTo or hasOne associations to the same table overwrite each other
# v1.3.6 #
- [BUG] don't update an existing updatedAt-attribute if timestamps option for a DAO is false
# v1.3.5 #
- [BUG] fixed missed DAO renaming in migrations (thanks to nov)
# v1.3.4 #
- [REFACTORING] renamed Model/ModelFactory/ModelFactoryManager to DAO/DAOFactory/DAOFactoryManager
- [IMPROVEMENT] `npm test` will run the test suite (thanks to gabrielfalcao)
- [IMPROVEMENT] documentation about setting up local development environment (thanks to gabrielfalcao)
- [REFACTORING] removed updatedAt + createdAt from SequelizeMeta
# v1.3.3 #
- [BUG] fixed sql-event emitter in all possible locations (thanks to megshark)
# v1.3.2 #
- [FEATURE] sqlite is now emitting the 'sql'-event as well (thanks to megshark)
......
......@@ -2,9 +2,9 @@ var Utils = require("./../utils")
, DataTypes = require('./../data-types')
module.exports = (function() {
var BelongsTo = function(srcModel, targetModel, options) {
this.source = srcModel
this.target = targetModel
var BelongsTo = function(srcDAO, targetDAO, options) {
this.source = srcDAO
this.target = targetDAO
this.options = options
this.isSelfAssociation = (this.source.tableName == this.target.tableName)
......@@ -13,7 +13,7 @@ module.exports = (function() {
this.associationAccessor = this.isSelfAssociation
? Utils.combineTableNames(this.target.tableName, this.options.as || this.target.tableName)
: this.target.tableName
: this.options.as || this.target.tableName
}
// the id is in the source table
......
......@@ -12,13 +12,13 @@ module.exports = (function() {
var customEventEmitter = new Utils.CustomEventEmitter(function() {
var where = {}
//fully qualify
where[self.__factory.connectorModel.tableName+"."+self.__factory.identifier] = self.instance.id
where[self.__factory.connectorDAO.tableName+"."+self.__factory.identifier] = self.instance.id
var primaryKeys = Utils._.keys(self.__factory.connectorModel.rawAttributes)
var primaryKeys = Utils._.keys(self.__factory.connectorDAO.rawAttributes)
, foreignKey = primaryKeys.filter(function(pk) { return pk != self.__factory.identifier })[0]
where[self.__factory.connectorModel.tableName+"."+foreignKey] = {join: self.__factory.target.tableName+".id"}
self.__factory.target.findAllJoin(self.__factory.connectorModel.tableName, {where: where})
where[self.__factory.connectorDAO.tableName+"."+foreignKey] = {join: self.__factory.target.tableName+".id"}
self.__factory.target.findAllJoin(self.__factory.connectorDAO.tableName, {where: where})
.on('success', function(objects) { customEventEmitter.emit('success', objects) })
.on('failure', function(err){ customEventEmitter.emit('failure', err) })
.on('sql', function(sql) { customEventEmitter.emit('sql', sql)})
......@@ -44,7 +44,7 @@ module.exports = (function() {
attributes[self.__factory.identifier] = self.instance.id
attributes[foreignIdentifier] = unassociatedObject.id
chainer.add(self.__factory.connectorModel.create(attributes))
chainer.add(self.__factory.connectorDAO.create(attributes))
})
chainer
......@@ -70,13 +70,13 @@ module.exports = (function() {
obsoleteAssociations.forEach(function(associatedObject) {
var where = {}
, primaryKeys = Utils._.keys(self.__factory.connectorModel.rawAttributes)
, primaryKeys = Utils._.keys(self.__factory.connectorDAO.rawAttributes)
, foreignKey = primaryKeys.filter(function(pk) { return pk != self.__factory.identifier })[0]
where[self.__factory.identifier] = self.instance.id
where[foreignKey] = associatedObject.id
self.__factory.connectorModel.find({where: where}).success(function(connector) {
self.__factory.connectorDAO.find({where: where}).success(function(connector) {
chainer.add(connector.destroy())
if(chainer.emitters.length == obsoleteAssociations.length) {
......
......@@ -5,9 +5,9 @@ var HasManySingleLinked = require("./has-many-single-linked")
, HasManyMultiLinked = require("./has-many-double-linked")
module.exports = (function() {
var HasMany = function(srcModel, targetModel, options) {
this.source = srcModel
this.target = targetModel
var HasMany = function(srcDAO, targetDAO, options) {
this.source = srcDAO
this.target = targetDAO
this.options = options
this.isSelfAssociation = (this.source.tableName == this.target.tableName)
......@@ -48,10 +48,10 @@ module.exports = (function() {
combinedTableAttributes[this.identifier] = {type:DataTypes.INTEGER, primaryKey: true}
combinedTableAttributes[this.foreignIdentifier] = {type:DataTypes.INTEGER, primaryKey: true}
this.connectorModel = this.source.modelFactoryManager.sequelize.define(this.combinedName, combinedTableAttributes, this.options)
if(!this.isSelfAssociation) this.target.associations[this.associationAccessor].connectorModel = this.connectorModel
this.connectorDAO = this.source.daoFactoryManager.sequelize.define(this.combinedName, combinedTableAttributes, this.options)
if(!this.isSelfAssociation) this.target.associations[this.associationAccessor].connectorDAO = this.connectorDAO
this.connectorModel.sync()
this.connectorDAO.sync()
} else {
var newAttributes = {}
newAttributes[this.identifier] = { type: DataTypes.INTEGER }
......@@ -65,7 +65,7 @@ module.exports = (function() {
var self = this
obj[this.accessors.get] = function() {
var Class = self.connectorModel ? HasManyMultiLinked : HasManySingleLinked
var Class = self.connectorDAO ? HasManyMultiLinked : HasManySingleLinked
return new Class(self, this).injectGetter()
}
......@@ -81,7 +81,7 @@ module.exports = (function() {
// define the returned customEventEmitter, which will emit the success event once everything is done
var customEventEmitter = new Utils.CustomEventEmitter(function() {
instance[self.accessors.get]().success(function(oldAssociatedObjects) {
var Class = self.connectorModel ? HasManyMultiLinked : HasManySingleLinked
var Class = self.connectorDAO ? HasManyMultiLinked : HasManySingleLinked
new Class(self, instance).injectSetter(customEventEmitter, oldAssociatedObjects, newAssociatedObjects)
})
})
......
......@@ -2,9 +2,9 @@ var Utils = require("./../utils")
, DataTypes = require('./../data-types')
module.exports = (function() {
var HasOne = function(srcModel, targetModel, options) {
this.source = srcModel
this.target = targetModel
var HasOne = function(srcDAO, targetDAO, options) {
this.source = srcDAO
this.target = targetDAO
this.options = options
this.isSelfAssociation = (this.source.tableName == this.target.tableName)
......@@ -13,7 +13,7 @@ module.exports = (function() {
this.associationAccessor = this.isSelfAssociation
? Utils.combineTableNames(this.target.tableName, this.options.as || this.target.tableName)
: this.target.tableName
: this.options.as || this.target.tableName
this.accessors = {
get: Utils._.camelize('get_' + (this.options.as || Utils.singularize(this.target.tableName))),
......
......@@ -6,21 +6,21 @@ var Utils = require("./../utils")
/* Defines Mixin for all models. */
var Mixin = module.exports = function(){}
Mixin.hasOne = function(associatedModel, options) {
Mixin.hasOne = function(associatedDAO, options) {
// the id is in the foreign table
var association = new HasOne(this, associatedModel, Utils._.extend((options||{}), this.options))
var association = new HasOne(this, associatedDAO, Utils._.extend((options||{}), this.options))
this.associations[association.associationAccessor] = association.injectAttributes()
return this
}
Mixin.belongsTo = function(associatedModel, options) {
Mixin.belongsTo = function(associatedDAO, options) {
// the id is in this table
var association = new BelongsTo(this, associatedModel, Utils._.extend((options||{}), this.options))
var association = new BelongsTo(this, associatedDAO, Utils._.extend((options||{}), this.options))
this.associations[association.associationAccessor] = association.injectAttributes()
return this
}
Mixin.hasMany = function(associatedModel, options) {
Mixin.hasMany = function(associatedDAO, options) {
// the id is in the foreign table or in a connecting table
var association = new HasMany(this, associatedModel, Utils._.extend((options||{}), this.options))
var association = new HasMany(this, associatedDAO, Utils._.extend((options||{}), this.options))
this.associations[association.associationAccessor] = association.injectAttributes()
return this
}
......
module.exports = (function() {
var DAOFactoryManager = function(sequelize) {
this.daos = []
this.sequelize = sequelize
}
DAOFactoryManager.prototype.addDAO = function(dao) {
this.daos.push(dao)
return dao
}
DAOFactoryManager.prototype.removeDAO = function(dao) {
this.daos = this.daos.filter(function(_dao) {
return _dao.name != dao.name
})
}
DAOFactoryManager.prototype.getDAO = function(daoName) {
var dao = this.daos.filter(function(dao) {
return dao.name == daoName
})
return !!dao ? dao[0] : null
}
DAOFactoryManager.prototype.__defineGetter__('all', function() {
return this.daos
})
return DAOFactoryManager
})()
var Utils = require("./utils")
, Model = require("./model")
, DAO = require("./dao")
, DataTypes = require("./data-types")
module.exports = (function() {
var ModelFactory = function(name, attributes, options) {
var DAOFactory = function(name, attributes, options) {
var self = this
this.options = Utils._.extend({
......@@ -19,37 +19,37 @@ module.exports = (function() {
this.name = name
this.tableName = this.options.freezeTableName ? name : Utils.pluralize(name)
this.rawAttributes = attributes
this.modelFactoryManager = null // defined in init function
this.daoFactoryManager = null // defined in init function
this.associations = {}
// extract validation
this.validate = this.options.validate || {}
}
Object.defineProperty(ModelFactory.prototype, 'attributes', {
Object.defineProperty(DAOFactory.prototype, 'attributes', {
get: function() {
return this.QueryGenerator.attributesToSQL(this.rawAttributes)
}
})
Object.defineProperty(ModelFactory.prototype, 'QueryInterface', {
get: function() { return this.modelFactoryManager.sequelize.getQueryInterface() }
Object.defineProperty(DAOFactory.prototype, 'QueryInterface', {
get: function() { return this.daoFactoryManager.sequelize.getQueryInterface() }
})
Object.defineProperty(ModelFactory.prototype, 'QueryGenerator', {
Object.defineProperty(DAOFactory.prototype, 'QueryGenerator', {
get: function() { return this.QueryInterface.QueryGenerator }
})
Object.defineProperty(ModelFactory.prototype, 'primaryKeyCount', {
Object.defineProperty(DAOFactory.prototype, 'primaryKeyCount', {
get: function() { return Utils._.keys(this.primaryKeys).length }
})
Object.defineProperty(ModelFactory.prototype, 'hasPrimaryKeys', {
Object.defineProperty(DAOFactory.prototype, 'hasPrimaryKeys', {
get: function() { return this.primaryKeyCount > 0 }
})
ModelFactory.prototype.init = function(modelFactoryManager) {
this.modelFactoryManager = modelFactoryManager
DAOFactory.prototype.init = function(daoFactoryManager) {
this.daoFactoryManager = daoFactoryManager
addDefaultAttributes.call(this)
addOptionalClassMethods.call(this)
......@@ -58,7 +58,7 @@ module.exports = (function() {
return this
}
ModelFactory.prototype.sync = function(options) {
DAOFactory.prototype.sync = function(options) {
options = Utils.merge(options || {}, this.options)
var self = this
......@@ -79,27 +79,28 @@ module.exports = (function() {
}).run()
}
ModelFactory.prototype.drop = function() {
DAOFactory.prototype.drop = function() {
return this.QueryInterface.dropTable(this.tableName)
}
ModelFactory.prototype.all = function() {
return this.findAll()
// alias for findAll
DAOFactory.prototype.all = function(options) {
return this.findAll(options)
}
ModelFactory.prototype.findAll = function(options) {
DAOFactory.prototype.findAll = function(options) {
return this.QueryInterface.select(this, this.tableName, options)
}
//right now, the caller (has-many-double-linked) is in charge of the where clause
ModelFactory.prototype.findAllJoin = function(joinTableName, options) {
DAOFactory.prototype.findAllJoin = function(joinTableName, options) {
optcpy = Utils._.clone(options)
optcpy.attributes = optcpy.attributes || [Utils.addTicks(this.tableName)+".*"]
return this.QueryInterface.select(this, [this.tableName, joinTableName], optcpy)
}
ModelFactory.prototype.find = function(options) {
DAOFactory.prototype.find = function(options) {
if([null, undefined].indexOf(options) > -1) {
var NullEmitter = require("./emitters/null-emitter")
return new NullEmitter()
......@@ -125,28 +126,28 @@ module.exports = (function() {
return this.QueryInterface.select(this, this.tableName, options, {plain: true})
}
ModelFactory.prototype.count = function(options) {
DAOFactory.prototype.count = function(options) {
options = Utils._.extend({ attributes: [] }, options || {})
options.attributes.push(['count(*)', 'count'])
return this.QueryInterface.rawSelect(this.tableName, options, 'count')
}
ModelFactory.prototype.max = function(field, options) {
DAOFactory.prototype.max = function(field, options) {
options = Utils._.extend({ attributes: [] }, options || {})
options.attributes.push(['max(' + field + ')', 'max'])
return this.QueryInterface.rawSelect(this.tableName, options, 'max')
}
ModelFactory.prototype.min = function(field, options) {
DAOFactory.prototype.min = function(field, options) {
options = Utils._.extend({ attributes: [] }, options || {})
options.attributes.push(['min(' + field + ')', 'min'])
return this.QueryInterface.rawSelect(this.tableName, options, 'min')
}
ModelFactory.prototype.build = function(values, options) {
var instance = new Model(values, Utils._.extend(this.options, this.attributes, { hasPrimaryKeys: this.hasPrimaryKeys }))
DAOFactory.prototype.build = function(values, options) {
var instance = new DAO(values, Utils._.extend(this.options, this.attributes, { hasPrimaryKeys: this.hasPrimaryKeys }))
, self = this
options = options || {}
......@@ -179,11 +180,11 @@ module.exports = (function() {
return instance
}
ModelFactory.prototype.create = function(values) {
DAOFactory.prototype.create = function(values) {
return this.build(values).save()
}
ModelFactory.prototype.__defineGetter__('primaryKeys', function() {
DAOFactory.prototype.__defineGetter__('primaryKeys', function() {
var result = {}
Utils._.each(this.attributes, function(dataTypeString, attributeName) {
if((attributeName != 'id') && (dataTypeString.indexOf('PRIMARY KEY') > -1))
......@@ -197,7 +198,7 @@ module.exports = (function() {
var query = function() {
var args = Utils._.map(arguments, function(arg, _) { return arg })
, s = this.modelFactoryManager.sequelize
, s = this.daoFactoryManager.sequelize
// add this as the second argument
if(arguments.length == 1) args.push(this)
......@@ -243,13 +244,13 @@ module.exports = (function() {
fields.forEach(function(field) {
if(self.autoIncrementField)
throw new Error('Invalid model definition. Only one autoincrement field allowed.')
throw new Error('Invalid DAO definition. Only one autoincrement field allowed.')
else
self.autoIncrementField = field
})
}
Utils._.extend(ModelFactory.prototype, require("./associations/mixin"))
Utils._.extend(DAOFactory.prototype, require("./associations/mixin"))
return ModelFactory
return DAOFactory
})()
......@@ -3,12 +3,12 @@ var Utils = require("./utils")
, Validator = require("validator")
module.exports = (function() {
var Model = function(values, options) {
var DAO = function(values, options) {
var self = this
this.attributes = []
this.validators = {} // holds validation settings for each attribute
this.__factory = null // will be set in Model.build
this.__factory = null // will be set in DAO.build
this.__options = Utils._.extend({
underscored: false,
hasPrimaryKeys: false,
......@@ -18,17 +18,17 @@ module.exports = (function() {
initAttributes.call(this, values)
}
Utils._.extend(Model.prototype, Mixin.prototype)
Utils._.extend(DAO.prototype, Mixin.prototype)
Object.defineProperty(Model.prototype, 'sequelize', {
get: function(){ return this.__factory.modelFactoryManager.sequelize }
Object.defineProperty(DAO.prototype, 'sequelize', {
get: function(){ return this.__factory.daoFactoryManager.sequelize }
})
Object.defineProperty(Model.prototype, 'QueryInterface', {
Object.defineProperty(DAO.prototype, 'QueryInterface', {
get: function(){ return this.sequelize.getQueryInterface() }
})
Object.defineProperty(Model.prototype, 'isDeleted', {
Object.defineProperty(DAO.prototype, 'isDeleted', {
get: function() {
var result = this.__options.timestamps && this.__options.paranoid
result = result && this[this.__options.underscored ? 'deleted_at' : 'deletedAt'] != null
......@@ -37,7 +37,7 @@ module.exports = (function() {
}
})
Object.defineProperty(Model.prototype, 'values', {
Object.defineProperty(DAO.prototype, 'values', {
get: function() {
var result = {}
, self = this
......@@ -50,7 +50,7 @@ module.exports = (function() {
}
})
Object.defineProperty(Model.prototype, 'primaryKeyValues', {
Object.defineProperty(DAO.prototype, 'primaryKeyValues', {
get: function() {
var result = {}
, self = this
......@@ -63,7 +63,7 @@ module.exports = (function() {
}
})
Object.defineProperty(Model.prototype, "identifiers", {
Object.defineProperty(DAO.prototype, "identifiers", {
get: function() {
var primaryKeys = Utils._.keys(this.__factory.primaryKeys)
, result = {}
......@@ -80,10 +80,10 @@ module.exports = (function() {
}
})
Model.prototype.save = function() {
DAO.prototype.save = function() {
var updatedAtAttr = this.__options.underscored ? 'updated_at' : 'updatedAt'
if(this.hasOwnProperty(updatedAtAttr))
if(this.__options.timestamps && this.hasOwnProperty(updatedAtAttr))
this[updatedAtAttr] = new Date()
if(this.isNewRecord) {
......@@ -98,11 +98,11 @@ module.exports = (function() {
}
/*
* Validate this model's attribute values according to validation rules set in the model definition.
* Validate this dao's attribute values according to validation rules set in the dao definition.
*
* @return null if and only if validation successful; otherwise an object containing { field name : [error msgs] } entries.
*/
Model.prototype.validate = function() {
DAO.prototype.validate = function() {
var self = this
var failures = {}
......@@ -163,7 +163,7 @@ module.exports = (function() {
}
Model.prototype.updateAttributes = function(updates) {
DAO.prototype.updateAttributes = function(updates) {
var self = this
var readOnlyAttributes = Utils._.keys(this.__factory.primaryKeys)
......@@ -184,7 +184,7 @@ module.exports = (function() {
return this.save()
}
Model.prototype.destroy = function() {
DAO.prototype.destroy = function() {
if(this.__options.timestamps && this.__options.paranoid) {
var attr = this.__options.underscored ? 'deleted_at' : 'deletedAt'
this[attr] = new Date()
......@@ -195,7 +195,7 @@ module.exports = (function() {
}
}
Model.prototype.equals = function(other) {
DAO.prototype.equals = function(other) {
var result = true
, self = this
......@@ -206,7 +206,7 @@ module.exports = (function() {
return result
}
Model.prototype.equalsOneOf = function(others) {
DAO.prototype.equalsOneOf = function(others) {
var result = false
, self = this
......@@ -215,12 +215,12 @@ module.exports = (function() {
return result
}
Model.prototype.addAttribute = function(attribute, value) {
DAO.prototype.addAttribute = function(attribute, value) {
this[attribute] = value
this.attributes.push(attribute)
}
Model.prototype.setValidators = function(attribute, validators) {
DAO.prototype.setValidators = function(attribute, validators) {
this.validators[attribute] = validators
}
......@@ -229,11 +229,11 @@ module.exports = (function() {
var initAttributes = function(values) {
var self = this
// add all passed values to the model and store the attribute names in this.attributes
// add all passed values to the dao and store the attribute names in this.attributes
Utils._.map(values, function(value, key) { self.addAttribute(key, value) })
// set id to null if not passed as value
// a newly created model has no id
// a newly created dao has no id
var defaults = this.__options.hasPrimaryKeys ? {} : { id: null }
if(this.__options.timestamps) {
......@@ -250,8 +250,8 @@ module.exports = (function() {
})
}
/* Add the instance methods to Model */
Utils._.extend(Model.prototype, Mixin.prototype)
/* Add the instance methods to DAO */
Utils._.extend(DAO.prototype, Mixin.prototype)
return Model
return DAO
})()
......@@ -121,22 +121,24 @@ module.exports = (function() {
}
}
Migrator.prototype.findOrCreateSequelizeMetaModel = function(syncOptions) {
Migrator.prototype.findOrCreateSequelizeMetaDAO = function(syncOptions) {
var self = this
return new Utils.CustomEventEmitter(function(emitter) {
var storedModel = self.sequelize.modelFactoryManager.getModel('SequelizeMeta')
, SequelizeMeta = storedModel
var storedDAO = self.sequelize.daoFactoryManager.getDAO('SequelizeMeta')
, SequelizeMeta = storedDAO
if(!storedModel) {
if(!storedDAO) {
SequelizeMeta = self.sequelize.define('SequelizeMeta', {
from: DataTypes.STRING,
to: DataTypes.STRING
}, {
timestamps: false
})
}
// force sync when model has newly created or if syncOptions are passed
if(!storedModel || syncOptions) {
if(!storedDAO || syncOptions) {
SequelizeMeta
.sync(syncOptions || {})
.success(function() { emitter.emit('success', SequelizeMeta) })
......@@ -153,7 +155,7 @@ module.exports = (function() {
var self = this
return new Utils.CustomEventEmitter(function(emitter) {
self.findOrCreateSequelizeMetaModel().success(function(SequelizeMeta) {
self.findOrCreateSequelizeMetaDAO().success(function(SequelizeMeta) {
SequelizeMeta.find({ order: 'id DESC' }).success(function(meta) {
emitter.emit('success', meta ? meta : null)
}).error(function(err) { emitter.emit('failure', err) })
......@@ -194,7 +196,7 @@ module.exports = (function() {
var saveSuccessfulMigration = function(from, to, callback) {
var self = this
self.findOrCreateSequelizeMetaModel().success(function(SequelizeMeta) {
self.findOrCreateSequelizeMetaDAO().success(function(SequelizeMeta) {
SequelizeMeta
.create({ from: from.migrationId, to: to.migrationId })
.success(callback)
......@@ -204,7 +206,7 @@ module.exports = (function() {
var deleteUndoneMigration = function(from, to, callback) {
var self = this
self.findOrCreateSequelizeMetaModel().success(function(SequelizeMeta) {
self.findOrCreateSequelizeMetaDAO().success(function(SequelizeMeta) {
SequelizeMeta
.find({ from: from.migrationId, to: to.migrationId })
.success(function(meta) {
......
module.exports = (function() {
var ModelFactoryManager = function(sequelize) {
this.models = []
this.sequelize = sequelize
}
ModelFactoryManager.prototype.addModel = function(model) {
this.models.push(model)
return model
}
ModelFactoryManager.prototype.removeModel = function(model) {
this.models = this.models.filter(function(_model) {
return _model.name != model.name
})
}
ModelFactoryManager.prototype.getModel = function(modelName) {
var model = this.models.filter(function(model) {
return model.name == modelName
})
return !!model ? model[0] : null
}
ModelFactoryManager.prototype.__defineGetter__('all', function() {
return this.models
})
return ModelFactoryManager
})()
......@@ -170,21 +170,21 @@ module.exports = (function() {
return queryAndEmit.call(this, sql, "removeIndex")
}
QueryInterface.prototype.insert = function(model, tableName, values) {
QueryInterface.prototype.insert = function(dao, tableName, values) {
var sql = this.QueryGenerator.insertQuery(tableName, values)
return queryAndEmit.call(this, [sql, model], 'insert', {
return queryAndEmit.call(this, [sql, dao], 'insert', {
success: function(obj) { obj.isNewRecord = false }
})
}
QueryInterface.prototype.update = function(model, tableName, values, identifier) {
QueryInterface.prototype.update = function(dao, tableName, values, identifier) {
var sql = this.QueryGenerator.updateQuery(tableName, values, identifier)
return queryAndEmit.call(this, [sql, model], 'update')
return queryAndEmit.call(this, [sql, dao], 'update')
}
QueryInterface.prototype.delete = function(model, tableName, identifier) {
QueryInterface.prototype.delete = function(dao, tableName, identifier) {
var sql = this.QueryGenerator.deleteQuery(tableName, identifier)
return queryAndEmit.call(this, [sql, model], 'delete')
return queryAndEmit.call(this, [sql, dao], 'delete')
}
QueryInterface.prototype.select = function(factory, tableName, options, queryOptions) {
......
var Utils = require("./utils")
, ModelFactory = require("./model-factory")
, DAOFactory = require("./dao-factory")
, DataTypes = require('./data-types')
, ModelFactoryManager = require("./model-factory-manager")
, DAOFactoryManager = require("./dao-factory-manager")
, Migrator = require("./migrator")
, QueryInterface = require("./query-interface")
......@@ -26,7 +26,7 @@ module.exports = (function() {
var ConnectorManager = require("./dialects/" + this.options.dialect + "/connector-manager")
this.modelFactoryManager = new ModelFactoryManager(this)
this.daoFactoryManager = new DAOFactoryManager(this)
this.connectorManager = new ConnectorManager(this, this.config)
}
......@@ -47,15 +47,15 @@ module.exports = (function() {
return this.migrator
}
Sequelize.prototype.define = function(modelName, attributes, options) {
Sequelize.prototype.define = function(daoName, attributes, options) {
options = options || {}
if(this.options.define)
options = Sequelize.Utils.merge(options, this.options.define)
var factory = new ModelFactory(modelName, attributes, options)
var factory = new DAOFactory(daoName, attributes, options)
this.modelFactoryManager.addModel(factory.init(this.modelFactoryManager))
this.daoFactoryManager.addDAO(factory.init(this.daoFactoryManager))
return factory
}
......@@ -89,7 +89,7 @@ module.exports = (function() {
return new Utils.CustomEventEmitter(function(emitter) {
var chainer = new Utils.QueryChainer
self.modelFactoryManager.models.forEach(function(model) { chainer.add(model.sync(options)) })
self.daoFactoryManager.daos.forEach(function(dao) { chainer.add(dao.sync(options)) })
chainer
.run()
......@@ -104,7 +104,7 @@ module.exports = (function() {
return new Utils.CustomEventEmitter(function(emitter) {
var chainer = new Utils.QueryChainer
self.modelFactoryManager.models.forEach(function(model) { chainer.add(model.drop()) })
self.daoFactoryManager.daos.forEach(function(dao) { chainer.add(dao.drop()) })
chainer
.run()
......
{
"name": "sqlize",
"name": "sequelize",
"description": "MySQL ORM for Node.JS",
"version": "1.3.2-1",
"version": "1.3.7",
"author": "Sascha Depold <sascha@depold.com>",
"contributors": [
{ "name": "Sascha Depold", "email": "sascha@depold.com" },
{ "name": "Meg Sharkey", "email": "meg@metamarkets.com" }
{ "name": "Meg Sharkey", "email": "meg@metamarkets.com" },
{ "name": "Chase Geigle", "email": "sky@skytrife.com" }
],
"dependencies": {
"mysql": "0.9.x",
......@@ -20,9 +21,11 @@
"jasmine-node": "1.0.x",
"sqlite3": ">=2.0.0"
},
"keywords": [],
"keywords": ["mysql", "orm", "nodejs", "object relational mapper"],
"main": "index",
"scripts": {},
"scripts": {
"test": "./node_modules/.bin/jasmine-node spec/"
},
"bin": {
"sequelize": "bin/sequelize"
},
......
......@@ -47,6 +47,17 @@ describe('BelongsTo', function() {
expect(task.getPerson).toBeDefined()
})
it("aliases associations to the same table according to the passed 'as' option", function() {
Task.belongsTo(User, {as: 'Poster'})
Task.belongsTo(User, {as: 'Owner'})
var task = Task.build({title: 'asd'})
expect(task.getPoster).toBeDefined()
expect(task.setPoster).toBeDefined()
expect(task.getOwner).toBeDefined()
expect(task.setOwner).toBeDefined()
})
it("intializes the foreign key with null", function() {
Task.belongsTo(User)
......
......@@ -103,13 +103,13 @@ describe('HasMany', function() {
expect(Task.attributes.UserId).toBeUndefined()
expect(User.attributes.UserId).toBeUndefined()
var models = sequelize.modelFactoryManager.models.filter(function(model) {
return (model.tableName == (Task.tableName + User.tableName))
var daos = sequelize.daoFactoryManager.daos.filter(function(dao) {
return (dao.tableName == (Task.tableName + User.tableName))
})
models.forEach(function(model) {
expect(model.attributes.UserId).toBeDefined()
expect(model.attributes.TaskId).toBeDefined()
daos.forEach(function(dao) {
expect(dao.attributes.UserId).toBeDefined()
expect(dao.attributes.TaskId).toBeDefined()
})
})
......@@ -123,13 +123,13 @@ describe('HasMany', function() {
expect(Task.attributes.user_id).toBeUndefined()
expect(User.attributes.user_id).toBeUndefined()
var models = sequelize.modelFactoryManager.models.filter(function(model) {
return (model.tableName == (Task.tableName + User.tableName))
var daos = sequelize.daoFactoryManager.daos.filter(function(dao) {
return (dao.tableName == (Task.tableName + User.tableName))
})
models.forEach(function(model) {
expect(model.attributes.user_id).toBeDefined()
expect(model.attributes.TaskId).toBeDefined()
daos.forEach(function(dao) {
expect(dao.attributes.user_id).toBeDefined()
expect(dao.attributes.TaskId).toBeDefined()
})
})
......@@ -137,13 +137,13 @@ describe('HasMany', function() {
User.hasMany(Task, { foreignKey: 'person_id' })
Task.hasMany(User, { foreignKey: 'work_item_id' })
var models = sequelize.modelFactoryManager.models.filter(function(model) {
return (model.tableName == (Task.tableName + User.tableName))
var daos = sequelize.daoFactoryManager.daos.filter(function(dao) {
return (dao.tableName == (Task.tableName + User.tableName))
})
models.forEach(function(model) {
expect(model.attributes.person_id).toBeDefined()
expect(model.attributes.work_item_id).toBeDefined()
daos.forEach(function(dao) {
expect(dao.attributes.person_id).toBeDefined()
expect(dao.attributes.work_item_id).toBeDefined()
})
})
......@@ -219,7 +219,7 @@ describe('HasMany', function() {
})
})
it("build the connector models name", function() {
it("build the connector daos name", function() {
Helpers.async(function(done) {
var Person = sequelize.define('Person', { name: Sequelize.STRING })
......@@ -228,11 +228,11 @@ describe('HasMany', function() {
Person.hasMany(Person, {as: 'CoWorkers'})
Person.sync({force: true}).success(function() {
var modelNames = sequelize.modelFactoryManager.models.map(function(model) { return model.tableName })
var daoNames = sequelize.daoFactoryManager.daos.map(function(dao) { return dao.tableName })
, expectation = ["Persons", "ChildrenPersons", "CoWorkersPersons", "FriendsPersons"]
expectation.forEach(function(ex) {
expect(modelNames.indexOf(ex) > -1).toBeTruthy()
expect(daoNames.indexOf(ex) > -1).toBeTruthy()
})
done()
......@@ -322,7 +322,7 @@ describe('HasMany', function() {
it("gets and sets the connector models", function() {
it("gets and sets the connector daos", function() {
Helpers.async(function(done) {
var Person = sequelize.define('Person', { name: Sequelize.STRING })
......
......@@ -54,6 +54,17 @@ describe('HasOne', function() {
expect(u.getWork).toBeDefined()
})
it("aliases associations to the same table according to the passed 'as' option", function() {
User.hasOne(Task, {as: 'Work'});
User.hasOne(Task, {as: 'Play'});
var u = User.build({username: 'asd'})
expect(u.getWork).toBeDefined()
expect(u.setWork).toBeDefined()
expect(u.getPlay).toBeDefined()
expect(u.setPlay).toBeDefined()
})
it("gets and sets the correct objects", function() {
var user, task;
......
......@@ -3,18 +3,18 @@ var Factories = module.exports = function(helpers) {
this.sequelize = this.helpers.sequelize
}
Factories.prototype.Model = function(modelName, options, callback, count) {
Factories.prototype.DAO = function(daoName, options, callback, count) {
count = count || 1
var self = this
, models = []
, daos = []
this.helpers.async(function(done) {
var Model = self.sequelize.modelFactoryManager.getModel(modelName)
var DAO = self.sequelize.daoFactoryManager.getDAO(daoName)
var create = function(cb) {
Model.create(options).on('success', function(model) {
models.push(model)
DAO.create(options).on('success', function(dao) {
daos.push(dao)
cb && cb()
}).on('failure', function(err) {
console.log(err)
......@@ -27,7 +27,7 @@ Factories.prototype.Model = function(modelName, options, callback, count) {
create(cb)
} else {
done()
callback && callback(models)
callback && callback(daos)
}
}
......@@ -36,5 +36,5 @@ Factories.prototype.Model = function(modelName, options, callback, count) {
}
Factories.prototype.User = function(options, callback, count) {
this.Model('User', options, callback, count)
this.DAO('User', options, callback, count)
}
......@@ -2,7 +2,7 @@ var config = require("./config/config")
, Sequelize = require("../index")
, dialects = ['sqlite', 'mysql']
describe('ModelFactory', function() {
describe('DAOFactory', function() {
dialects.forEach(function(dialect) {
describe('with dialect "' + dialect + '"', function() {
var User = null
......@@ -37,12 +37,12 @@ describe('ModelFactory', function() {
afterEach(function() { Helpers.dropAllTables() })
describe('constructor', function() {
it("uses the passed model name as tablename if freezeTableName", function() {
it("uses the passed dao name as tablename if freezeTableName", function() {
var User = sequelize.define('User', {}, {freezeTableName: true})
expect(User.tableName).toEqual('User')
})
it("uses the pluralized modelname as tablename unless freezeTableName", function() {
it("uses the pluralized daoname as tablename unless freezeTableName", function() {
var User = sequelize.define('User', {}, {freezeTableName: false})
expect(User.tableName).toEqual('Users')
})
......@@ -66,7 +66,7 @@ describe('ModelFactory', function() {
userid: {type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true},
userscore: {type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true},
})
}).toThrow('Invalid model definition. Only one autoincrement field allowed.')
}).toThrow('Invalid DAO definition. Only one autoincrement field allowed.')
})
})
......@@ -199,7 +199,7 @@ describe('ModelFactory', function() {
})
describe('destroy', function() {
it('deletes a record from the database if model is not paranoid', function() {
it('deletes a record from the database if dao is not paranoid', function() {
Helpers.async(function(done) {
User = sequelize.define('User', {
name: Sequelize.STRING,
......@@ -246,7 +246,7 @@ describe('ModelFactory', function() {
})
})
it('marks the database entry as deleted if model is paranoid', function() {
it('marks the database entry as deleted if dao is paranoid', function() {
Helpers.async(function(done) {
User = sequelize.define('User', {
name: Sequelize.STRING, bio: Sequelize.TEXT
......@@ -305,7 +305,7 @@ describe('ModelFactory', function() {
})
})
it('returns a single model', function() {
it('returns a single dao', function() {
Helpers.async(function(done) {
User.find(users[0].id).success(function(user) {
expect(Array.isArray(user)).toBeFalsy()
......@@ -635,12 +635,12 @@ describe('ModelFactory', function() {
})
describe('Mixin', function() {
var ModelFactory = require("../lib/model-factory")
var DAOFactory = require("../lib/dao-factory")
it("adds the mixed-in functions to the model", function() {
expect(ModelFactory.prototype.hasOne).toBeDefined()
expect(ModelFactory.prototype.hasMany).toBeDefined()
expect(ModelFactory.prototype.belongsTo).toBeDefined()
it("adds the mixed-in functions to the dao", function() {
expect(DAOFactory.prototype.hasOne).toBeDefined()
expect(DAOFactory.prototype.hasMany).toBeDefined()
expect(DAOFactory.prototype.belongsTo).toBeDefined()
})
})
......
......@@ -2,7 +2,7 @@ var config = require("./config/config")
, Sequelize = require("../index")
, dialects = ['sqlite', 'mysql']
describe('Model', function() {
describe('DAO', function() {
dialects.forEach(function(dialect) {
describe('with dialect "' + dialect + '"', function() {
var User = null
......@@ -374,6 +374,30 @@ describe('Model', function() {
}, 10)
})
})
describe('without timestamps option', function() {
var User2 = sequelize.define('User2', {
username: Sequelize.STRING,
updatedAt: Sequelize.DATE
}, {
timestamps: false
})
beforeEach(function() {
Helpers.async(function(done) {
User2.sync({ force: true }).success(done)
})
})
it("doesn't update the updatedAt column", function() {
Helpers.async(function(done) {
User2.create({ username: 'john doe' }).success(function(johnDoe) {
expect(johnDoe.updatedAt).toBeNull()
done()
})
})
})
})
})
describe('updateAttributes', function() {
......
......@@ -18,7 +18,7 @@ describe('Migrator', function() {
migrator = new Migrator(sequelize, options)
migrator
.findOrCreateSequelizeMetaModel({ force: true })
.findOrCreateSequelizeMetaDAO({ force: true })
.success(function(_SequelizeMeta) {
SequelizeMeta = _SequelizeMeta
done()
......
......@@ -18,18 +18,18 @@ describe('HasMany', function() {
beforeEach(function() {
Helpers.async(function(_done) {
Helpers.Factories.Model(User.name, {name: 'User' + Math.random()}, function(_users) {
Helpers.Factories.DAO(User.name, {name: 'User' + Math.random()}, function(_users) {
users = _users; _done()
}, 5)
})
Helpers.async(function(_done) {
Helpers.Factories.Model(Task.name, {name: 'Task' + Math.random()}, function(_tasks) {
Helpers.Factories.DAO(Task.name, {name: 'Task' + Math.random()}, function(_tasks) {
tasks = _tasks; _done()
}, 2)
})
})
describe('addModel / getModel', function() {
describe('addDAO / getDAO', function() {
var user = null
, task = null
......@@ -46,7 +46,7 @@ describe('HasMany', function() {
})
})
it('should correctly add an association to the model', function() {
it('should correctly add an association to the dao', function() {
Helpers.async(function(done) {
user.getTasks().on('success', function(_tasks) {
expect(_tasks.length).toEqual(0)
......@@ -61,7 +61,7 @@ describe('HasMany', function() {
})
})
describe('removeModel', function() {
describe('removeDAO', function() {
var user = null
, tasks = null
......
......@@ -19,7 +19,7 @@ describe('Associations', function() {
it("should create a table wp_table1wp_table2s", function() {
Helpers.async(function(done) {
expect(sequelize.modelFactoryManager.getModel('wp_table1swp_table2s')).toBeDefined()
expect(sequelize.daoFactoryManager.getDAO('wp_table1swp_table2s')).toBeDefined()
done()
})
})
......@@ -32,10 +32,10 @@ describe('Associations', function() {
Table2.hasMany(Table1, {joinTableName: 'table1_to_table2'})
it("should not use a combined name", function() {
expect(sequelize.modelFactoryManager.getModel('ms_table1sms_table2s')).toBeUndefined()
expect(sequelize.daoFactoryManager.getDAO('ms_table1sms_table2s')).toBeUndefined()
})
it("should use the specified name", function() {
expect(sequelize.modelFactoryManager.getModel('table1_to_table2')).toBeDefined()
expect(sequelize.daoFactoryManager.getDAO('table1_to_table2')).toBeDefined()
})
})
})
......
......@@ -3,7 +3,7 @@ var config = require("../config/config")
, sequelize = new Sequelize(config.database, config.username, config.password, { logging: false })
, Helpers = new (require("../config/helpers"))(sequelize)
describe('ModelFactory', function() {
describe('DAOFactory', function() {
beforeEach(function() { Helpers.sync() })
afterEach(function() { Helpers.drop() })
......
......@@ -22,8 +22,8 @@ describe('Sequelize', function() {
it('should pass the global options correctly', function() {
setup({ logging: false, define: { underscored:true } })
var Model = sequelize.define('model', {name: Sequelize.STRING})
expect(Model.options.underscored).toBeTruthy()
var DAO = sequelize.define('dao', {name: Sequelize.STRING})
expect(DAO.options.underscored).toBeTruthy()
})
it('should correctly set the host and the port', function() {
......@@ -35,15 +35,15 @@ describe('Sequelize', function() {
})
describe('define', function() {
it("adds a new model to the model manager", function() {
expect(sequelize.modelFactoryManager.all.length).toEqual(0)
it("adds a new dao to the dao manager", function() {
expect(sequelize.daoFactoryManager.all.length).toEqual(0)
sequelize.define('foo', { title: Sequelize.STRING })
expect(sequelize.modelFactoryManager.all.length).toEqual(1)
expect(sequelize.daoFactoryManager.all.length).toEqual(1)
})
})
describe('sync', function() {
it("synchronizes all models", function() {
it("synchronizes all daos", function() {
var Project = sequelize.define('project' + config.rand(), { title: Sequelize.STRING })
var Task = sequelize.define('task' + config.rand(), { title: Sequelize.STRING })
......@@ -58,7 +58,7 @@ describe('Sequelize', function() {
})
describe('import', function() {
it("imports a model definition from a file", function() {
it("imports a dao definition from a file", function() {
var Project = sequelize.import(__dirname + "/assets/project")
expect(Project).toBeDefined()
})
......
......@@ -3,7 +3,7 @@ var config = require("../config/config")
, dbFile = __dirname + '/test.sqlite'
, storages = [':memory:', dbFile]
describe('ModelFactory', function() {
describe('DAOFactory', function() {
storages.forEach(function(storage) {
describe('with storage "' + storage + '"', function() {
var User = null
......@@ -68,7 +68,7 @@ describe('ModelFactory', function() {
Helpers.async(function(done) {
var options = JSON.stringify({ foo: 'bar', bar: 'foo' })
Helpers.Factories.Model('Person', {
Helpers.Factories.DAO('Person', {
name: 'John Doe',
options: options
}, function(people) {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!