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

Commit 7c5379d4 by Sascha Depold

Merge branch 'proto_rewrite' of git://github.com/innofluence/sequelize into inno…

…fluence-proto_rewrite
2 parents 54a15e66 f145957c
......@@ -20,6 +20,4 @@ language: node_js
node_js:
- 0.6
- 0.8
- 0.9
- 0.9
\ No newline at end of file
......@@ -25,6 +25,10 @@ module.exports = (function() {
this.identifier = this.options.foreignKey || Utils._.underscoredIf(Utils.singularize(this.target.tableName) + "Id", this.source.options.underscored)
newAttributes[this.identifier] = { type: DataTypes.INTEGER }
Utils._.defaults(this.source.rawAttributes, newAttributes)
// Sync attributes to DAO proto each time a new assoc is added
this.target.DAO.prototype.attributes = Object.keys(this.target.DAO.prototype.rawAttributes);
return this
}
......@@ -33,7 +37,7 @@ module.exports = (function() {
, accessor = Utils._.camelize('get_' + (this.options.as || Utils.singularize(this.target.tableName)))
obj[accessor] = function() {
var id = obj[self.identifier]
var id = this[self.identifier]
return self.target.find(id)
}
......@@ -45,10 +49,10 @@ module.exports = (function() {
, accessor = Utils._.camelize('set_' + (this.options.as || Utils.singularize(this.target.tableName)))
obj[accessor] = function(associatedObject) {
obj[self.identifier] = associatedObject ? associatedObject.id : null
this[self.identifier] = associatedObject ? associatedObject.id : null
// passes the changed field to save, so only that field get updated.
return obj.save([ self.identifier ])
return this.save([ self.identifier ])
}
return this
......
......@@ -68,6 +68,10 @@ module.exports = (function() {
Utils._.defaults(this.target.rawAttributes, newAttributes)
}
// Sync attributes to DAO proto each time a new assoc is added
this.target.DAO.prototype.attributes = Object.keys(this.target.DAO.prototype.rawAttributes);
this.source.DAO.prototype.attributes = Object.keys(this.source.DAO.prototype.rawAttributes);
return this
}
......
......@@ -31,6 +31,9 @@ module.exports = (function() {
newAttributes[this.identifier] = { type: DataTypes.INTEGER }
Utils._.defaults(this.target.rawAttributes, newAttributes)
// Sync attributes to DAO proto each time a new assoc is added
this.target.DAO.prototype.attributes = Object.keys(this.target.DAO.prototype.rawAttributes);
return this
}
......@@ -38,7 +41,7 @@ module.exports = (function() {
var self = this
obj[this.accessors.get] = function() {
var id = obj.id
var id = this.id
, where = {}
where[self.identifier] = id
......@@ -53,15 +56,16 @@ module.exports = (function() {
, options = self.options || {}
obj[this.accessors.set] = function(associatedObject) {
var instance = this;
return new Utils.CustomEventEmitter(function(emitter) {
obj[self.accessors.get]().success(function(oldObj) {
instance[self.accessors.get]().success(function(oldObj) {
if(oldObj) {
oldObj[self.identifier] = null
oldObj.save()
}
if(associatedObject) {
associatedObject[self.identifier] = obj.id
associatedObject[self.identifier] = instance.id
associatedObject
.save()
.success(function() { emitter.emit('success', associatedObject) })
......
......@@ -10,6 +10,10 @@ Mixin.hasOne = function(associatedDAO, options) {
// the id is in the foreign table
var association = new HasOne(this, associatedDAO, Utils._.extend((options||{}), this.options))
this.associations[association.associationAccessor] = association.injectAttributes()
association.injectGetter(this.DAO.prototype);
association.injectSetter(this.DAO.prototype);
return this
}
......@@ -17,6 +21,10 @@ Mixin.belongsTo = function(associatedDAO, options) {
// the id is in this table
var association = new BelongsTo(this, associatedDAO, Utils._.extend((options||{}), this.options))
this.associations[association.associationAccessor] = association.injectAttributes()
association.injectGetter(this.DAO.prototype);
association.injectSetter(this.DAO.prototype);
return this
}
......@@ -24,6 +32,10 @@ Mixin.hasMany = function(associatedDAO, options) {
// the id is in the foreign table or in a connecting table
var association = new HasMany(this, associatedDAO, Utils._.extend((options||{}), this.options))
this.associations[association.associationAccessor] = association.injectAttributes()
association.injectGetter(this.DAO.prototype);
association.injectSetter(this.DAO.prototype);
return this
}
......
var Utils = require("./utils")
, DAO = require("./dao")
, DataTypes = require("./data-types")
, Util = require('util')
module.exports = (function() {
var DAOFactory = function(name, attributes, options) {
......@@ -41,21 +42,60 @@ module.exports = (function() {
get: function() { return this.QueryInterface.QueryGenerator }
})
Object.defineProperty(DAOFactory.prototype, 'primaryKeyCount', {
get: function() { return Utils._.keys(this.primaryKeys).length }
})
Object.defineProperty(DAOFactory.prototype, 'hasPrimaryKeys', {
get: function() { return this.primaryKeyCount > 0 }
})
DAOFactory.prototype.init = function(daoFactoryManager) {
var self = this;
this.daoFactoryManager = daoFactoryManager
this.primaryKeys = {};
Utils._.each(this.attributes, function(dataTypeString, attributeName) {
if((attributeName != 'id') && (dataTypeString.indexOf('PRIMARY KEY') !== -1)) {
self.primaryKeys[attributeName] = dataTypeString
}
})
this.primaryKeyCount = Utils._.keys(this.primaryKeys).length;
this.options.hasPrimaryKeys = this.hasPrimaryKeys = this.primaryKeyCount > 0;
addDefaultAttributes.call(this)
addOptionalClassMethods.call(this)
findAutoIncrementField.call(this)
// DAO prototype
this.DAO = function() {
DAO.apply(this, arguments);
};
Util.inherits(this.DAO, DAO);
this.DAO.prototype.rawAttributes = this.rawAttributes;
if (this.options.instanceMethods) {
Utils._.each(this.options.instanceMethods, function(fct, name) {
self.DAO.prototype[name] = fct
})
}
this.DAO.prototype.attributes = Object.keys(this.DAO.prototype.rawAttributes);
this.DAO.prototype.booleanValues = [];
this.DAO.prototype.defaultValues = {};
this.DAO.prototype.validators = {};
Utils._.each(this.rawAttributes, function (definition, name) {
if(((definition === DataTypes.BOOLEAN) || (definition.type === DataTypes.BOOLEAN))) {
self.DAO.prototype.booleanValues.push(name);
}
if(definition.hasOwnProperty('defaultValue')) {
self.DAO.prototype.defaultValues[name] = function() {
return Utils.toDefaultValue(definition.defaultValue);
}
}
if (definition.hasOwnProperty('validate')) {
self.DAO.prototype.validators[name] = definition.validate;
}
});
this.DAO.prototype.__factory = this;
this.DAO.prototype.hasDefaultValues = !Utils._.isEmpty(this.DAO.prototype.defaultValues);
return this
}
......@@ -188,44 +228,12 @@ module.exports = (function() {
}
DAOFactory.prototype.build = function(values, options) {
var instance = new DAO(values, Utils._.extend(this.options, { hasPrimaryKeys: this.hasPrimaryKeys, factory: this }))
, self = this
options = options || {}
instance.__factory = this
Utils._.each(this.attributes, function(definition, name) {
//transform integer 0,1 into boolean
if((definition.indexOf(DataTypes.BOOLEAN) !== -1) && (typeof instance[name] === "number")) {
instance[name] = (instance[name] !== 0)
}
//add default attributes
if(typeof instance[name] === 'undefined') {
var value = null
if(self.rawAttributes.hasOwnProperty(name) && self.rawAttributes[name].hasOwnProperty('defaultValue')) {
value = Utils.toDefaultValue(self.rawAttributes[name].defaultValue)
}
instance[name] = value
instance.addAttribute(name, value)
}
var self = this
, instance = new this.DAO(values, this.options)
// add validation
if (self.rawAttributes.hasOwnProperty(name) && self.rawAttributes[name].hasOwnProperty('validate')) {
instance.setValidators(name, self.rawAttributes[name].validate)
}
})
Utils._.each(this.options.instanceMethods || {}, function(fct, name) { instance[name] = fct })
Utils._.each(this.associations, function(association) {
association.injectGetter(instance)
association.injectSetter(instance)
})
instance.isNewRecord = options.hasOwnProperty('isNewRecord') ? options.isNewRecord : true
instance.selectedValues = values
instance.isNewRecord = options.hasOwnProperty('isNewRecord') ? options.isNewRecord : true
return instance
}
......@@ -234,17 +242,6 @@ module.exports = (function() {
return this.build(values).save(fields)
}
DAOFactory.prototype.__defineGetter__('primaryKeys', function() {
var result = {}
Utils._.each(this.attributes, function(dataTypeString, attributeName) {
if((attributeName != 'id') && (dataTypeString.indexOf('PRIMARY KEY') !== -1)) {
result[attributeName] = dataTypeString
}
})
return result
})
// private
var query = function() {
......
var Utils = require("./utils")
, Mixin = require("./associations/mixin")
, Validator = require("validator")
, DataTypes = require("./data-types")
module.exports = (function() {
var DAO = function(values, options) {
this.attributes = []
this.validators = {} // holds validation settings for each attribute
this.__factory = options.factory || null // will be set by DAO.build if not present
this.__options = Utils._.extend({
underscored: false,
hasPrimaryKeys: false,
timestamps: true,
paranoid: false
}, options || {})
var self = this;
this.__options = options;
this.hasPrimaryKeys = options.hasPrimaryKeys;
this.selectedValues = values;
initAttributes.call(this, values)
if (this.hasDefaultValues) {
Utils._.each(this.defaultValues, function (value, name) {
if(typeof self[name] === 'undefined') {
self.addAttribute(name, value());
}
})
}
if (this.booleanValues.length) {
this.booleanValues.forEach(function (name) {
//transform integer 0,1 into boolean
self[name] = !!self[name];
});
}
}
Utils._.extend(DAO.prototype, Mixin.prototype)
......@@ -242,7 +253,6 @@ module.exports = (function() {
DAO.prototype.addAttribute = function(attribute, value) {
this[attribute] = value
this.attributes.push(attribute)
}
DAO.prototype.setValidators = function(attribute, validators) {
......@@ -265,7 +275,7 @@ module.exports = (function() {
// set id to null if not passed as value
// a newly created dao has no id
var defaults = this.__options.hasPrimaryKeys ? {} : { id: null }
var defaults = this.hasPrimaryKeys ? {} : { id: null }
if(this.__options.timestamps) {
defaults[this.__options.underscored ? 'created_at' : 'createdAt'] = new Date()
......@@ -276,17 +286,16 @@ module.exports = (function() {
}
}
for (var attr in defaults) {
var value = defaults[attr]
if (Utils._.size(defaults)) {
for (var attr in defaults) {
var value = defaults[attr]
if(!this.hasOwnProperty(attr)) {
this.addAttribute(attr, Utils.toDefaultValue(value))
if(!this.hasOwnProperty(attr)) {
this.addAttribute(attr, Utils.toDefaultValue(value))
}
}
}
}
/* Add the instance methods to DAO */
Utils._.extend(DAO.prototype, Mixin.prototype)
return DAO
})()
......@@ -62,7 +62,7 @@ describe('BelongsTo', function() {
Task.belongsTo(User)
var task = Task.build({title: 'asd'})
expect(task['UserId']).toBeNull()
expect(task['UserId']).not.toBeDefined();
})
it("sets and gets the correct objects", function() {
......
......@@ -229,7 +229,8 @@ describe('DAO', function() {
it("doesn't update the updatedAt column", function() {
Helpers.async(function(done) {
User2.create({ username: 'john doe' }).success(function(johnDoe) {
expect(johnDoe.updatedAt).toBeNull()
// sqlite and mysql return undefined, whereas postgres returns null
expect([undefined, null].indexOf(johnDoe.updatedAt)).not.toBe(-1);
done()
})
})
......
......@@ -86,7 +86,7 @@ describe("[" + dialect.toUpperCase() + "] DAOFactory", function() {
})
expect(Task.build().title).toEqual('a task!')
expect(Task.build().foo).toEqual(2)
expect(Task.build().bar).toEqual(null)
expect(Task.build().bar).toEqual(undefined)
expect(Task.build().foobar).toEqual('asd')
expect(Task.build().flag).toEqual(false)
})
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!