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

Commit ab1b3093 by Jan Aagaard Meier

refactor DAO to use prototyping

1 parent 45fce2bf
......@@ -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
}
......
......@@ -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
}
......
......@@ -26,12 +26,6 @@ module.exports = (function() {
// extract validation
this.validate = this.options.validate || {}
// DAO prototype
this.DAO = function() {
DAO.apply(this, arguments);
};
Util.inherits(this.DAO, DAO);
}
Object.defineProperty(DAOFactory.prototype, 'attributes', {
......@@ -48,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
}
......@@ -195,40 +228,12 @@ module.exports = (function() {
}
DAOFactory.prototype.build = function(values, options) {
var instance = new this.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)
}
// 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 })
var self = this
, instance = new this.DAO(values, this.options)
instance.isNewRecord = options.hasOwnProperty('isNewRecord') ? options.isNewRecord : true
instance.selectedValues = values
instance.isNewRecord = options.hasOwnProperty('isNewRecord') ? options.isNewRecord : true
return instance
}
......@@ -237,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,7 @@ module.exports = (function() {
DAO.prototype.addAttribute = function(attribute, value) {
this[attribute] = value
this.attributes.push(attribute)
// this.attributes.push(attribute)
}
DAO.prototype.setValidators = function(attribute, validators) {
......@@ -265,7 +276,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,11 +287,13 @@ 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))
}
}
}
}
......
......@@ -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()
})
})
......
......@@ -2,6 +2,7 @@ var config = module.exports
config["node tests"] = {
environment: "node",
timeout: 500,
rootPath: "../",
tests: [
"spec/**/*.spec.js"
......
......@@ -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)
})
......
......@@ -6,6 +6,7 @@ if(typeof require === 'function') {
}
buster.spec.expose()
buster.timeout = 500;
describe("[" + dialect.toUpperCase() + "] DAO", function() {
describe('validations', function() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!