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

Commit 33ff3ad5 by Ruben Bridgewater

Remove unnecessary indentation

1 parent 073f1777
var Association = function() {
var Association = function () {};
};
module.exports = Association;
\ No newline at end of file
......@@ -6,176 +6,174 @@ var Utils = require('./../utils')
, Association = require('./base')
, util = require('util');
module.exports = (function() {
var BelongsTo = function(source, target, options) {
Association.call(this);
this.associationType = 'BelongsTo';
this.source = source;
this.target = target;
this.options = options;
this.scope = options.scope;
this.isSingleAssociation = true;
this.isSelfAssociation = (this.source === this.target);
this.as = this.options.as;
if (Utils._.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else {
this.foreignKeyAttribute = {};
this.foreignKey = this.options.foreignKey;
}
if (this.as) {
this.isAliased = true;
this.options.name = {
singular: this.as
};
} else {
this.as = this.target.options.name.singular;
this.options.name = this.target.options.name;
}
if (!this.options.foreignKey) {
this.options.foreignKey = Utils._.camelizeIf(
[
Utils._.underscoredIf(this.as, this.source.options.underscored),
this.target.primaryKeyAttribute
].join('_'),
!this.source.options.underscored
);
}
var BelongsTo = function(source, target, options) {
Association.call(this);
this.associationType = 'BelongsTo';
this.source = source;
this.target = target;
this.options = options;
this.scope = options.scope;
this.isSingleAssociation = true;
this.isSelfAssociation = (this.source === this.target);
this.as = this.options.as;
if (Utils._.isObject(this.options.foreignKey)) {
this.foreignKeyAttribute = this.options.foreignKey;
this.foreignKey = this.foreignKeyAttribute.name || this.foreignKeyAttribute.fieldName;
} else {
this.foreignKeyAttribute = {};
this.foreignKey = this.options.foreignKey;
}
if (this.as) {
this.isAliased = true;
this.options.name = {
singular: this.as
};
} else {
this.as = this.target.options.name.singular;
this.options.name = this.target.options.name;
}
this.identifier = this.foreignKey || Utils._.camelizeIf(
if (!this.options.foreignKey) {
this.options.foreignKey = Utils._.camelizeIf(
[
Utils._.underscoredIf(this.options.name.singular, this.target.options.underscored),
Utils._.underscoredIf(this.as, this.source.options.underscored),
this.target.primaryKeyAttribute
].join('_'),
!this.target.options.underscored
!this.source.options.underscored
);
this.targetIdentifier = this.target.primaryKeyAttribute;
this.associationAccessor = this.as;
this.options.useHooks = options.useHooks;
// Get singular name, trying to uppercase the first letter, unless the model forbids it
var singular = Utils.uppercaseFirst(this.options.name.singular);
this.accessors = {
get: 'get' + singular,
set: 'set' + singular,
create: 'create' + singular
};
}
this.identifier = this.foreignKey || Utils._.camelizeIf(
[
Utils._.underscoredIf(this.options.name.singular, this.target.options.underscored),
this.target.primaryKeyAttribute
].join('_'),
!this.target.options.underscored
);
this.targetIdentifier = this.target.primaryKeyAttribute;
this.associationAccessor = this.as;
this.options.useHooks = options.useHooks;
// Get singular name, trying to uppercase the first letter, unless the model forbids it
var singular = Utils.uppercaseFirst(this.options.name.singular);
this.accessors = {
get: 'get' + singular,
set: 'set' + singular,
create: 'create' + singular
};
};
util.inherits(BelongsTo, Association);
util.inherits(BelongsTo, Association);
// the id is in the source table
BelongsTo.prototype.injectAttributes = function() {
var newAttributes = {};
// the id is in the source table
BelongsTo.prototype.injectAttributes = function() {
var newAttributes = {};
newAttributes[this.identifier] = Utils._.defaults(this.foreignKeyAttribute, { type: this.options.keyType || this.target.rawAttributes[this.targetIdentifier].type });
if (this.options.constraints !== false) {
this.options.onDelete = this.options.onDelete || 'SET NULL';
this.options.onUpdate = this.options.onUpdate || 'CASCADE';
}
Helpers.addForeignKeyConstraints(newAttributes[this.identifier], this.target, this.source, this.options);
Utils.mergeDefaults(this.source.rawAttributes, newAttributes);
newAttributes[this.identifier] = Utils._.defaults(this.foreignKeyAttribute, { type: this.options.keyType || this.target.rawAttributes[this.targetIdentifier].type });
if (this.options.constraints !== false) {
this.options.onDelete = this.options.onDelete || 'SET NULL';
this.options.onUpdate = this.options.onUpdate || 'CASCADE';
}
Helpers.addForeignKeyConstraints(newAttributes[this.identifier], this.target, this.source, this.options);
Utils.mergeDefaults(this.source.rawAttributes, newAttributes);
this.identifierField = this.source.rawAttributes[this.identifier].field || this.identifier;
this.identifierField = this.source.rawAttributes[this.identifier].field || this.identifier;
this.source.refreshAttributes();
this.source.refreshAttributes();
Helpers.checkNamingCollision(this);
Helpers.checkNamingCollision(this);
return this;
};
return this;
};
// Add getAssociation method to the prototype of the model instance
BelongsTo.prototype.injectGetter = function(instancePrototype) {
var association = this;
// Add getAssociation method to the prototype of the model instance
BelongsTo.prototype.injectGetter = function(instancePrototype) {
var association = this;
instancePrototype[this.accessors.get] = function(options) {
var where = {};
where[association.targetIdentifier] = this.get(association.identifier);
instancePrototype[this.accessors.get] = function(options) {
var where = {};
where[association.targetIdentifier] = this.get(association.identifier);
options = association.target.__optClone(options) || {};
options = association.target.__optClone(options) || {};
options.where = {
$and: [
options.where,
where
]
};
options.where = {
$and: [
options.where,
where
]
};
if (options.limit === undefined) options.limit = null;
if (options.limit === undefined) options.limit = null;
var model = association.target;
if (options.hasOwnProperty('scope')) {
if (!options.scope) {
model = model.unscoped();
} else {
model = model.scope(options.scope);
}
var model = association.target;
if (options.hasOwnProperty('scope')) {
if (!options.scope) {
model = model.unscoped();
} else {
model = model.scope(options.scope);
}
}
return model.find(options);
};
return this;
return model.find(options);
};
// Add setAssociaton method to the prototype of the model instance
BelongsTo.prototype.injectSetter = function(instancePrototype) {
var association = this;
return this;
};
instancePrototype[this.accessors.set] = function(associatedInstance, options) {
options = options || {};
// Add setAssociaton method to the prototype of the model instance
BelongsTo.prototype.injectSetter = function(instancePrototype) {
var association = this;
var value = associatedInstance;
if (associatedInstance instanceof association.target.Instance) {
value = associatedInstance[association.targetIdentifier];
}
instancePrototype[this.accessors.set] = function(associatedInstance, options) {
options = options || {};
this.set(association.identifier, value);
var value = associatedInstance;
if (associatedInstance instanceof association.target.Instance) {
value = associatedInstance[association.targetIdentifier];
}
if (options.save === false) return;
this.set(association.identifier, value);
options = Utils._.extend({
fields: [association.identifier],
allowNull: [association.identifier],
association: true
}, options);
if (options.save === false) return;
options = Utils._.extend({
fields: [association.identifier],
allowNull: [association.identifier],
association: true
}, options);
// passes the changed field to save, so only that field get updated.
return this.save(options);
};
return this;
// passes the changed field to save, so only that field get updated.
return this.save(options);
};
// Add createAssociation method to the prototype of the model instance
BelongsTo.prototype.injectCreator = function(instancePrototype) {
var association = this;
return this;
};
instancePrototype[this.accessors.create] = function(values, fieldsOrOptions) {
var instance = this
, options = {};
// Add createAssociation method to the prototype of the model instance
BelongsTo.prototype.injectCreator = function(instancePrototype) {
var association = this;
if ((fieldsOrOptions || {}).transaction instanceof Transaction) {
options.transaction = fieldsOrOptions.transaction;
}
options.logging = (fieldsOrOptions || {}).logging;
instancePrototype[this.accessors.create] = function(values, fieldsOrOptions) {
var instance = this
, options = {};
return association.target.create(values, fieldsOrOptions).then(function(newAssociatedObject) {
return instance[association.accessors.set](newAssociatedObject, options);
});
};
if ((fieldsOrOptions || {}).transaction instanceof Transaction) {
options.transaction = fieldsOrOptions.transaction;
}
options.logging = (fieldsOrOptions || {}).logging;
return this;
return association.target.create(values, fieldsOrOptions).then(function(newAssociatedObject) {
return instance[association.accessors.set](newAssociatedObject, options);
});
};
return BelongsTo;
})();
return this;
};
module.exports = BelongsTo;
......@@ -3,135 +3,133 @@
var Utils = require('./../utils')
, _ = require('lodash');
module.exports = (function() {
var HasManySingleLinked = function(association, instance) {
this.association = association;
this.instance = instance;
this.target = this.association.target;
this.source = this.association.source;
var HasManySingleLinked = function(association, instance) {
this.association = association;
this.instance = instance;
this.target = this.association.target;
this.source = this.association.source;
};
HasManySingleLinked.prototype.injectGetter = function(options) {
var scopeWhere = this.association.scope ? {} : null;
if (this.association.scope) {
Object.keys(this.association.scope).forEach(function (attribute) {
scopeWhere[attribute] = this.association.scope[attribute];
}.bind(this));
}
options.where = {
$and: [
new Utils.where(
this.target.rawAttributes[this.association.identifier],
this.instance[this.source.primaryKeyAttribute]
),
scopeWhere,
options.where
]
};
HasManySingleLinked.prototype.injectGetter = function(options) {
var scopeWhere = this.association.scope ? {} : null;
var model = this.association.target;
if (options.hasOwnProperty('scope')) {
if (!options.scope) {
model = model.unscoped();
} else {
model = model.scope(options.scope);
}
}
return model.all(options);
};
HasManySingleLinked.prototype.injectSetter = function(oldAssociations, newAssociations, defaultAttributes) {
var self = this
, primaryKeys
, primaryKey
, updateWhere
, associationKeys = Object.keys((oldAssociations[0] || newAssociations[0] || {Model: {primaryKeys: {}}}).Model.primaryKeys || {})
, associationKey = (associationKeys.length === 1) ? associationKeys[0] : 'id'
, options = defaultAttributes
, promises = []
, obsoleteAssociations = oldAssociations.filter(function(old) {
return !Utils._.find(newAssociations, function(obj) {
return obj[associationKey] === old[associationKey];
});
})
, unassociatedObjects = newAssociations.filter(function(obj) {
return !Utils._.find(oldAssociations, function(old) {
return obj[associationKey] === old[associationKey];
});
})
, update;
if (obsoleteAssociations.length > 0) {
// clear the old associations
var obsoleteIds = obsoleteAssociations.map(function(associatedObject) {
associatedObject[self.association.identifier] = (newAssociations.length < 1 ? null : self.instance.id);
return associatedObject[associationKey];
});
update = {};
update[self.association.identifier] = null;
primaryKeys = Object.keys(this.association.target.primaryKeys);
primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : 'id';
updateWhere = {};
updateWhere[primaryKey] = obsoleteIds;
promises.push(this.association.target.unscoped().update(
update,
Utils._.extend(options, {
allowNull: [self.association.identifier],
where: updateWhere
})
));
}
if (unassociatedObjects.length > 0) {
// For the self.instance
var pkeys = Object.keys(self.instance.Model.primaryKeys)
, pkey = pkeys.length === 1 ? pkeys[0] : 'id';
primaryKeys = Object.keys(this.association.target.primaryKeys);
primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : 'id';
updateWhere = {};
// set the new associations
var unassociatedIds = unassociatedObjects.map(function(associatedObject) {
associatedObject[self.association.identifier] = self.instance[pkey] || self.instance.id;
return associatedObject[associationKey];
});
update = {};
update[self.association.identifier] = (newAssociations.length < 1 ? null : self.instance[pkey] || self.instance.id);
if (this.association.scope) {
Object.keys(this.association.scope).forEach(function (attribute) {
scopeWhere[attribute] = this.association.scope[attribute];
}.bind(this));
_.assign(update, this.association.scope);
}
options.where = {
$and: [
new Utils.where(
this.target.rawAttributes[this.association.identifier],
this.instance[this.source.primaryKeyAttribute]
),
scopeWhere,
options.where
]
};
var model = this.association.target;
if (options.hasOwnProperty('scope')) {
if (!options.scope) {
model = model.unscoped();
} else {
model = model.scope(options.scope);
}
}
updateWhere[primaryKey] = unassociatedIds;
return model.all(options);
};
promises.push(this.association.target.unscoped().update(
update,
Utils._.extend(options, {
allowNull: [self.association.identifier],
where: updateWhere
})
));
}
HasManySingleLinked.prototype.injectSetter = function(oldAssociations, newAssociations, defaultAttributes) {
var self = this
, primaryKeys
, primaryKey
, updateWhere
, associationKeys = Object.keys((oldAssociations[0] || newAssociations[0] || {Model: {primaryKeys: {}}}).Model.primaryKeys || {})
, associationKey = (associationKeys.length === 1) ? associationKeys[0] : 'id'
, options = defaultAttributes
, promises = []
, obsoleteAssociations = oldAssociations.filter(function(old) {
return !Utils._.find(newAssociations, function(obj) {
return obj[associationKey] === old[associationKey];
});
})
, unassociatedObjects = newAssociations.filter(function(obj) {
return !Utils._.find(oldAssociations, function(old) {
return obj[associationKey] === old[associationKey];
});
})
, update;
if (obsoleteAssociations.length > 0) {
// clear the old associations
var obsoleteIds = obsoleteAssociations.map(function(associatedObject) {
associatedObject[self.association.identifier] = (newAssociations.length < 1 ? null : self.instance.id);
return associatedObject[associationKey];
});
update = {};
update[self.association.identifier] = null;
primaryKeys = Object.keys(this.association.target.primaryKeys);
primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : 'id';
updateWhere = {};
updateWhere[primaryKey] = obsoleteIds;
promises.push(this.association.target.unscoped().update(
update,
Utils._.extend(options, {
allowNull: [self.association.identifier],
where: updateWhere
})
));
}
return Utils.Promise.all(promises);
};
if (unassociatedObjects.length > 0) {
// For the self.instance
var pkeys = Object.keys(self.instance.Model.primaryKeys)
, pkey = pkeys.length === 1 ? pkeys[0] : 'id';
primaryKeys = Object.keys(this.association.target.primaryKeys);
primaryKey = primaryKeys.length === 1 ? primaryKeys[0] : 'id';
updateWhere = {};
// set the new associations
var unassociatedIds = unassociatedObjects.map(function(associatedObject) {
associatedObject[self.association.identifier] = self.instance[pkey] || self.instance.id;
return associatedObject[associationKey];
});
update = {};
update[self.association.identifier] = (newAssociations.length < 1 ? null : self.instance[pkey] || self.instance.id);
if (this.association.scope) {
_.assign(update, this.association.scope);
}
updateWhere[primaryKey] = unassociatedIds;
promises.push(this.association.target.unscoped().update(
update,
Utils._.extend(options, {
allowNull: [self.association.identifier],
where: updateWhere
})
));
}
HasManySingleLinked.prototype.injectAdder = function(newAssociation, options) {
newAssociation.set(this.association.identifier, this.instance.get(this.instance.Model.primaryKeyAttribute));
if (this.association.scope) {
Object.keys(this.association.scope).forEach(function (attribute) {
newAssociation.set(attribute, this.association.scope[attribute]);
}.bind(this));
}
return Utils.Promise.all(promises);
};
HasManySingleLinked.prototype.injectAdder = function(newAssociation, options) {
newAssociation.set(this.association.identifier, this.instance.get(this.instance.Model.primaryKeyAttribute));
if (this.association.scope) {
Object.keys(this.association.scope).forEach(function (attribute) {
newAssociation.set(attribute, this.association.scope[attribute]);
}.bind(this));
}
return newAssociation.save(options);
};
return newAssociation.save(options);
};
return HasManySingleLinked;
})();
module.exports = HasManySingleLinked;
......@@ -2,48 +2,50 @@
var Utils = require('./../utils');
module.exports = {
checkNamingCollision: function (association) {
if (association.source.rawAttributes.hasOwnProperty(association.as)) {
throw new Error(
'Naming collision between attribute \'' + association.as +
'\' and association \'' + association.as + '\' on model ' + association.source.name +
'. To remedy this, change either foreignKey or as in your association definition'
);
}
},
addForeignKeyConstraints: function(newAttribute, source, target, options) {
// FK constraints are opt-in: users must either set `foreignKeyConstraints`
// on the association, or request an `onDelete` or `onUpdate` behaviour
if (options.foreignKeyConstraint || options.onDelete || options.onUpdate) {
// Find primary keys: composite keys not supported with this approach
var primaryKeys = Utils._.chain(source.rawAttributes).keys()
.filter(function(key) { return source.rawAttributes[key].primaryKey; })
.map(function(key) { return source.rawAttributes[key].field || key; }).value();
if (primaryKeys.length === 1) {
if (!!source.options.schema) {
newAttribute.references = {
model: source.modelManager.sequelize.queryInterface.QueryGenerator.addSchema({
tableName: source.tableName,
options: {
schema: source.options.schema,
schemaDelimiter: source.options.schemaDelimiter
}
})
};
} else {
newAttribute.references = { model: source.tableName };
}
newAttribute.references.key = primaryKeys[0];
newAttribute.onDelete = options.onDelete;
newAttribute.onUpdate = options.onUpdate;
function checkNamingCollision (association) {
if (association.source.rawAttributes.hasOwnProperty(association.as)) {
throw new Error(
'Naming collision between attribute \'' + association.as +
'\' and association \'' + association.as + '\' on model ' + association.source.name +
'. To remedy this, change either foreignKey or as in your association definition'
);
}
}
function addForeignKeyConstraints (newAttribute, source, target, options) {
// FK constraints are opt-in: users must either set `foreignKeyConstraints`
// on the association, or request an `onDelete` or `onUpdate` behaviour
if (options.foreignKeyConstraint || options.onDelete || options.onUpdate) {
// Find primary keys: composite keys not supported with this approach
var primaryKeys = Utils._.chain(source.rawAttributes).keys()
.filter(function(key) { return source.rawAttributes[key].primaryKey; })
.map(function(key) { return source.rawAttributes[key].field || key; }).value();
if (primaryKeys.length === 1) {
if (!!source.options.schema) {
newAttribute.references = {
model: source.modelManager.sequelize.queryInterface.QueryGenerator.addSchema({
tableName: source.tableName,
options: {
schema: source.options.schema,
schemaDelimiter: source.options.schemaDelimiter
}
})
};
} else {
newAttribute.references = { model: source.tableName };
}
newAttribute.references.key = primaryKeys[0];
newAttribute.onDelete = options.onDelete;
newAttribute.onUpdate = options.onUpdate;
}
}
}
module.exports = {
checkNamingCollision: checkNamingCollision,
addForeignKeyConstraints: addForeignKeyConstraints
};
This diff could not be displayed because it is too large.
......@@ -2,15 +2,17 @@
var hstore = require('pg-hstore')({sanitize : true});
module.exports = {
stringify: function(data) {
if(data === null) return null;
function stringify (data) {
if (data === null) return null;
return hstore.stringify(data);
},
parse: function(value) {
if(value === null) return null;
}
function parse (value) {
if (value === null) return null;
return hstore.parse(value);
}
}
module.exports = {
stringify: stringify,
parse: parse
};
......@@ -3,60 +3,64 @@
var Utils = require('../../utils'),
moment = require('moment');
module.exports = {
stringify: function (data) {
if (data === null) return null;
function stringify (data) {
if (data === null) return null;
if (!Utils._.isArray(data) || data.length !== 2) return '';
if (!Utils._.isArray(data) || data.length !== 2) return '';
if (Utils._.any(data, Utils._.isNull)) return '';
if (Utils._.any(data, Utils._.isNull)) return '';
if (data.hasOwnProperty('inclusive')) {
if (!data.inclusive) data.inclusive = [false, false];
else if (data.inclusive === true) data.inclusive = [true, true];
} else {
data.inclusive = [false, false];
}
if (data.hasOwnProperty('inclusive')) {
if (!data.inclusive) data.inclusive = [false, false];
else if (data.inclusive === true) data.inclusive = [true, true];
} else {
data.inclusive = [false, false];
Utils._.each(data, function (value, index) {
if (Utils._.isObject(value)) {
if (value.hasOwnProperty('inclusive')) data.inclusive[index] = !!value.inclusive;
if (value.hasOwnProperty('value')) data[index] = value.value;
}
});
return (data.inclusive[0] ? '[' : '(') + JSON.stringify(data[0]) + ',' + JSON.stringify(data[1]) + (data.inclusive[1] ? ']' : ')');
}
function parse (value, AttributeType) {
if (value === null) return null;
if(typeof AttributeType === 'function') AttributeType = new AttributeType();
AttributeType = AttributeType || ''; // if attribute is not defined, assign empty string in order to prevent
// AttributeType.toString() to fail with uncaught exception later in the code
var result = value
.substring(1, value.length - 1)
.split(',', 2);
Utils._.each(data, function (value, index) {
if (Utils._.isObject(value)) {
if (value.hasOwnProperty('inclusive')) data.inclusive[index] = !!value.inclusive;
if (value.hasOwnProperty('value')) data[index] = value.value;
if (result.length !== 2) return value;
result = result
.map(function (value) {
switch (AttributeType.toString()) {
case 'int4range':
return parseInt(value, 10);
case 'numrange':
return parseFloat(value);
case 'daterange':
case 'tsrange':
case 'tstzrange':
return moment(value).toDate();
}
return value;
});
return (data.inclusive[0] ? '[' : '(') + JSON.stringify(data[0]) + ',' + JSON.stringify(data[1]) + (data.inclusive[1] ? ']' : ')');
},
parse: function (value, AttributeType) {
if (value === null) return null;
if(typeof AttributeType === 'function') AttributeType = new AttributeType();
AttributeType = AttributeType || ''; // if attribute is not defined, assign empty string in order to prevent
// AttributeType.toString() to fail with uncaught exception later in the code
var result = value
.substring(1, value.length - 1)
.split(',', 2);
if (result.length !== 2) return value;
result = result
.map(function (value) {
switch (AttributeType.toString()) {
case 'int4range':
return parseInt(value, 10);
case 'numrange':
return parseFloat(value);
case 'daterange':
case 'tsrange':
case 'tstzrange':
return moment(value).toDate();
}
return value;
});
result.inclusive = [(value[0] === '['), (value[value.length - 1] === ']')];
return result;
}
result.inclusive = [(value[0] === '['), (value[value.length - 1] === ']')];
return result;
}
module.exports = {
stringify: stringify,
parse: parse
};
......@@ -9,106 +9,111 @@ var Utils = require('../../utils')
@class QueryInterface
@static
*/
module.exports = {
/**
A wrapper that fixes SQLite's inability to remove columns from existing tables.
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but without the obsolete column.
@method removeColumn
@for QueryInterface
@param {String} tableName The name of the table.
@param {String} attributeName The name of the attribute that we want to remove.
@param {Object} options
@param {Boolean|Function} [options.logging] A function that logs the sql queries, or false for explicitly not logging these queries
@param {CustomEventEmitter} emitter The EventEmitter from outside.
@param {Function} queryAndEmit The function from outside that triggers some events to get triggered.
@since 1.6.0
*/
removeColumn: function(tableName, attributeName, options) {
var self = this;
options = options || {};
return this.describeTable(tableName).then(function(fields) {
delete fields[attributeName];
var sql = self.QueryGenerator.removeColumnQuery(tableName, fields)
, subQueries = sql.split(';').filter(function(q) { return q !== ''; });
return Promise.each(subQueries, function(subQuery) {
return self.sequelize.query(subQuery + ';', { raw: true, logging: options.logging });
});
/**
A wrapper that fixes SQLite's inability to remove columns from existing tables.
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but without the obsolete column.
@method removeColumn
@for QueryInterface
@param {String} tableName The name of the table.
@param {String} attributeName The name of the attribute that we want to remove.
@param {Object} options
@param {Boolean|Function} [options.logging] A function that logs the sql queries, or false for explicitly not logging these queries
@param {CustomEventEmitter} emitter The EventEmitter from outside.
@param {Function} queryAndEmit The function from outside that triggers some events to get triggered.
@since 1.6.0
*/
var removeColumn = function(tableName, attributeName, options) {
var self = this;
options = options || {};
return this.describeTable(tableName).then(function(fields) {
delete fields[attributeName];
var sql = self.QueryGenerator.removeColumnQuery(tableName, fields)
, subQueries = sql.split(';').filter(function(q) { return q !== ''; });
return Promise.each(subQueries, function(subQuery) {
return self.sequelize.query(subQuery + ';', { raw: true, logging: options.logging });
});
},
/**
A wrapper that fixes SQLite's inability to change columns from existing tables.
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but with a modified version of the respective column.
@method changeColumn
@for QueryInterface
@param {String} tableName The name of the table.
@param {Object} attributes An object with the attribute's name as key and it's options as value object.
@param {Object} options
@param {Boolean|Function} [options.logging] A function that logs the sql queries, or false for explicitly not logging these queries
@param {CustomEventEmitter} emitter The EventEmitter from outside.
@param {Function} queryAndEmit The function from outside that triggers some events to get triggered.
@since 1.6.0
*/
changeColumn: function(tableName, attributes, options) {
var attributeName = Utils._.keys(attributes)[0]
, self = this;
options = options || {};
return this.describeTable(tableName).then(function(fields) {
fields[attributeName] = attributes[attributeName];
var sql = self.QueryGenerator.removeColumnQuery(tableName, fields)
, subQueries = sql.split(';').filter(function(q) { return q !== ''; });
return Promise.each(subQueries, function(subQuery) {
return self.sequelize.query(subQuery + ';', { raw: true, logging: options.logging });
});
});
};
/**
A wrapper that fixes SQLite's inability to change columns from existing tables.
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but with a modified version of the respective column.
@method changeColumn
@for QueryInterface
@param {String} tableName The name of the table.
@param {Object} attributes An object with the attribute's name as key and it's options as value object.
@param {Object} options
@param {Boolean|Function} [options.logging] A function that logs the sql queries, or false for explicitly not logging these queries
@param {CustomEventEmitter} emitter The EventEmitter from outside.
@param {Function} queryAndEmit The function from outside that triggers some events to get triggered.
@since 1.6.0
*/
var changeColumn = function(tableName, attributes, options) {
var attributeName = Utils._.keys(attributes)[0]
, self = this;
options = options || {};
return this.describeTable(tableName).then(function(fields) {
fields[attributeName] = attributes[attributeName];
var sql = self.QueryGenerator.removeColumnQuery(tableName, fields)
, subQueries = sql.split(';').filter(function(q) { return q !== ''; });
return Promise.each(subQueries, function(subQuery) {
return self.sequelize.query(subQuery + ';', { raw: true, logging: options.logging });
});
},
/**
A wrapper that fixes SQLite's inability to rename columns from existing tables.
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but with a renamed version of the respective column.
@method renameColumn
@for QueryInterface
@param {String} tableName The name of the table.
@param {String} attrNameBefore The name of the attribute before it was renamed.
@param {String} attrNameAfter The name of the attribute after it was renamed.
@param {Object} options
@param {Boolean|Function} [options.logging] A function that logs the sql queries, or false for explicitly not logging these queries
@param {CustomEventEmitter} emitter The EventEmitter from outside.
@param {Function} queryAndEmit The function from outside that triggers some events to get triggered.
@since 1.6.0
*/
renameColumn: function(tableName, attrNameBefore, attrNameAfter, options) {
var self = this;
options = options || {};
return this.describeTable(tableName).then(function(fields) {
fields[attrNameAfter] = Utils._.clone(fields[attrNameBefore]);
delete fields[attrNameBefore];
var sql = self.QueryGenerator.renameColumnQuery(tableName, attrNameBefore, attrNameAfter, fields)
, subQueries = sql.split(';').filter(function(q) { return q !== ''; });
return Promise.each(subQueries, function(subQuery) {
return self.sequelize.query(subQuery + ';', { raw: true, logging: options.logging });
});
});
};
/**
A wrapper that fixes SQLite's inability to rename columns from existing tables.
It will create a backup of the table, drop the table afterwards and create a
new table with the same name but with a renamed version of the respective column.
@method renameColumn
@for QueryInterface
@param {String} tableName The name of the table.
@param {String} attrNameBefore The name of the attribute before it was renamed.
@param {String} attrNameAfter The name of the attribute after it was renamed.
@param {Object} options
@param {Boolean|Function} [options.logging] A function that logs the sql queries, or false for explicitly not logging these queries
@param {CustomEventEmitter} emitter The EventEmitter from outside.
@param {Function} queryAndEmit The function from outside that triggers some events to get triggered.
@since 1.6.0
*/
var renameColumn = function(tableName, attrNameBefore, attrNameAfter, options) {
var self = this;
options = options || {};
return this.describeTable(tableName).then(function(fields) {
fields[attrNameAfter] = Utils._.clone(fields[attrNameBefore]);
delete fields[attrNameBefore];
var sql = self.QueryGenerator.renameColumnQuery(tableName, attrNameBefore, attrNameAfter, fields)
, subQueries = sql.split(';').filter(function(q) { return q !== ''; });
return Promise.each(subQueries, function(subQuery) {
return self.sequelize.query(subQuery + ';', { raw: true, logging: options.logging });
});
}
});
};
module.exports = {
removeColumn: removeColumn,
changeColumn: changeColumn,
renameColumn: renameColumn
};
\ No newline at end of file
......@@ -4,100 +4,98 @@ var Toposort = require('toposort-class')
, Utils = require('./utils')
, _ = require('lodash');
module.exports = (function() {
var ModelManager = function(sequelize) {
this.models = [];
this.sequelize = sequelize;
};
ModelManager.prototype.addModel = function(model) {
this.models.push(model);
this.sequelize.models[model.name] = model;
return model;
};
ModelManager.prototype.removeModel = function(model) {
this.models = this.models.filter(function($model) {
return $model.name !== model.name;
});
var ModelManager = function(sequelize) {
this.models = [];
this.sequelize = sequelize;
};
delete this.sequelize.models[model.name];
};
ModelManager.prototype.addModel = function(model) {
this.models.push(model);
this.sequelize.models[model.name] = model;
ModelManager.prototype.getModel = function(against, options) {
options = _.defaults(options || {}, {
attribute: 'name'
});
return model;
};
var model = this.models.filter(function(model) {
return model[options.attribute] === against;
});
ModelManager.prototype.removeModel = function(model) {
this.models = this.models.filter(function($model) {
return $model.name !== model.name;
});
return !!model ? model[0] : null;
};
delete this.sequelize.models[model.name];
};
ModelManager.prototype.__defineGetter__('all', function() {
return this.models;
ModelManager.prototype.getModel = function(against, options) {
options = _.defaults(options || {}, {
attribute: 'name'
});
/**
* Iterate over Models in an order suitable for e.g. creating tables. Will
* take foreign key constraints into account so that dependencies are visited
* before dependents.
*/
ModelManager.prototype.forEachModel = function(iterator, options) {
var models = {}
, sorter = new Toposort()
, sorted
, dep;
options = _.defaults(options || {}, {
reverse: true
});
var model = this.models.filter(function(model) {
return model[options.attribute] === against;
});
this.models.forEach(function(model) {
var deps = []
, tableName = model.getTableName();
return !!model ? model[0] : null;
};
ModelManager.prototype.__defineGetter__('all', function() {
return this.models;
});
/**
* Iterate over Models in an order suitable for e.g. creating tables. Will
* take foreign key constraints into account so that dependencies are visited
* before dependents.
*/
ModelManager.prototype.forEachModel = function(iterator, options) {
var models = {}
, sorter = new Toposort()
, sorted
, dep;
options = _.defaults(options || {}, {
reverse: true
});
if (_.isObject(tableName)) {
tableName = tableName.schema + '.' + tableName.tableName;
}
this.models.forEach(function(model) {
var deps = []
, tableName = model.getTableName();
models[tableName] = model;
if (_.isObject(tableName)) {
tableName = tableName.schema + '.' + tableName.tableName;
}
for (var attrName in model.rawAttributes) {
if (model.rawAttributes.hasOwnProperty(attrName)) {
var attribute = model.rawAttributes[attrName];
models[tableName] = model;
if (attribute.references) {
attribute = Utils.formatReferences(attribute);
dep = attribute.references.model;
for (var attrName in model.rawAttributes) {
if (model.rawAttributes.hasOwnProperty(attrName)) {
var attribute = model.rawAttributes[attrName];
if (_.isObject(dep)) {
dep = dep.schema + '.' + dep.tableName;
}
if (attribute.references) {
attribute = Utils.formatReferences(attribute);
dep = attribute.references.model;
deps.push(dep);
if (_.isObject(dep)) {
dep = dep.schema + '.' + dep.tableName;
}
deps.push(dep);
}
}
}
deps = deps.filter(function(dep) {
return tableName !== dep;
});
sorter.add(tableName, deps);
deps = deps.filter(function(dep) {
return tableName !== dep;
});
sorted = sorter.sort();
if (options.reverse) {
sorted = sorted.reverse();
}
sorted.forEach(function(name) {
iterator(models[name], name);
});
};
sorter.add(tableName, deps);
});
sorted = sorter.sort();
if (options.reverse) {
sorted = sorted.reverse();
}
sorted.forEach(function(name) {
iterator(models[name], name);
});
};
return ModelManager;
})();
module.exports = ModelManager;
This diff could not be displayed because it is too large.
'use strict';
module.exports = (function() {
var Attribute = function(options) {
var Attribute = function(options) {
if (options.type === undefined) options = {type: options};
this.type = options.type;
};
};
return Attribute;
})();
module.exports = Attribute;
......@@ -5,175 +5,173 @@ var Utils = require('./../utils')
, DataTypes = require('../data-types')
, Promise = require('bluebird');
module.exports = (function() {
var CounterCache = function(association, options) {
this.association = association;
this.source = association.source;
this.target = association.target;
this.options = options || {};
this.sequelize = this.source.modelManager.sequelize;
this.as = this.options.as;
if (association.associationType !== 'HasMany') {
throw new Error('Can only have CounterCache on HasMany association');
}
var CounterCache = function(association, options) {
this.association = association;
this.source = association.source;
this.target = association.target;
this.options = options || {};
this.sequelize = this.source.modelManager.sequelize;
this.as = this.options.as;
if (association.associationType !== 'HasMany') {
throw new Error('Can only have CounterCache on HasMany association');
}
if (this.as) {
this.isAliased = true;
this.columnName = this.as;
} else {
this.as = 'count_' + this.target.options.name.plural;
this.columnName = Utils._.camelizeIf(
this.as,
!this.source.options.underscored
);
}
this.injectAttributes();
this.injectHooks();
};
// Add countAssociation attribute to source model
CounterCache.prototype.injectAttributes = function() {
// Do not try to use a column that's already taken
Helpers.checkNamingCollision(this);
var newAttributes = {};
newAttributes[this.columnName] = {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: Utils._.partial(
Utils.toDefaultValue,
0
)
};
if (this.as) {
this.isAliased = true;
this.columnName = this.as;
} else {
this.as = 'count_' + this.target.options.name.plural;
this.columnName = Utils._.camelizeIf(
this.as,
!this.source.options.underscored
);
}
Utils.mergeDefaults(this.source.rawAttributes, newAttributes);
this.injectAttributes();
this.injectHooks();
};
// Sync attributes and setters/getters to DAO prototype
this.source.refreshAttributes();
};
// Add setAssociaton method to the prototype of the model instance
CounterCache.prototype.injectHooks = function() {
var association = this.association,
counterCacheInstance = this,
CounterUtil,
fullUpdateHook,
atomicHooks,
previousTargetId;
CounterUtil = {
update: function (targetId) {
var query = CounterUtil._targetQuery(targetId);
return association.target.count({ where: query }).then(function (count) {
var newValues = {};
// Add countAssociation attribute to source model
CounterCache.prototype.injectAttributes = function() {
// Do not try to use a column that's already taken
Helpers.checkNamingCollision(this);
query = CounterUtil._sourceQuery(targetId);
var newAttributes = {};
newValues[counterCacheInstance.columnName] = count;
newAttributes[this.columnName] = {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: Utils._.partial(
Utils.toDefaultValue,
0
)
};
return association.source.update(newValues, { where: query });
});
},
increment: function (targetId) {
var query = CounterUtil._sourceQuery(targetId);
Utils.mergeDefaults(this.source.rawAttributes, newAttributes);
return association.source.find({ where: query }).then(function (instance) {
return instance.increment(counterCacheInstance.columnName, { by: 1 });
});
},
decrement: function (targetId) {
var query = CounterUtil._sourceQuery(targetId);
// Sync attributes and setters/getters to DAO prototype
this.source.refreshAttributes();
return association.source.find({ where: query }).then(function (instance) {
return instance.decrement(counterCacheInstance.columnName, { by: 1 });
});
},
// helpers
_targetQuery: function (id) {
var query = {};
query[association.identifier] = id;
return query;
},
_sourceQuery: function (id) {
var query = {};
query[association.source.primaryKeyAttribute] = id;
return query;
}
};
// Add setAssociaton method to the prototype of the model instance
CounterCache.prototype.injectHooks = function() {
var association = this.association,
counterCacheInstance = this,
CounterUtil,
fullUpdateHook,
atomicHooks,
previousTargetId;
CounterUtil = {
update: function (targetId) {
var query = CounterUtil._targetQuery(targetId);
return association.target.count({ where: query }).then(function (count) {
var newValues = {};
query = CounterUtil._sourceQuery(targetId);
newValues[counterCacheInstance.columnName] = count;
return association.source.update(newValues, { where: query });
});
},
increment: function (targetId) {
var query = CounterUtil._sourceQuery(targetId);
return association.source.find({ where: query }).then(function (instance) {
return instance.increment(counterCacheInstance.columnName, { by: 1 });
});
},
decrement: function (targetId) {
var query = CounterUtil._sourceQuery(targetId);
return association.source.find({ where: query }).then(function (instance) {
return instance.decrement(counterCacheInstance.columnName, { by: 1 });
});
},
// helpers
_targetQuery: function (id) {
var query = {};
query[association.identifier] = id;
return query;
},
_sourceQuery: function (id) {
var query = {};
query[association.source.primaryKeyAttribute] = id;
return query;
}
};
fullUpdateHook = function (target) {
var targetId = target.get(association.identifier)
, promises = [];
fullUpdateHook = function (target) {
var targetId = target.get(association.identifier)
, promises = [];
if (targetId) {
promises.push(CounterUtil.update(targetId));
}
if (previousTargetId && previousTargetId !== targetId) {
promises.push(CounterUtil.update(previousTargetId));
}
return Promise.all(promises).return(undefined);
};
atomicHooks = {
create: function (target) {
var targetId = target.get(association.identifier);
if (targetId) {
promises.push(CounterUtil.update(targetId));
return CounterUtil.increment(targetId);
}
},
update: function (target) {
var targetId = target.get(association.identifier)
, promises = [];
if (previousTargetId && previousTargetId !== targetId) {
promises.push(CounterUtil.update(previousTargetId));
if (targetId && !previousTargetId) {
promises.push(CounterUtil.increment(targetId));
}
if (!targetId && previousTargetId) {
promises.push(CounterUtil.decrement(targetId));
}
if (previousTargetId && targetId && previousTargetId !== targetId) {
promises.push(CounterUtil.increment(targetId));
promises.push(CounterUtil.decrement(previousTargetId));
}
return Promise.all(promises);
},
destroy: function (target) {
var targetId = target.get(association.identifier);
return Promise.all(promises).return(undefined);
};
atomicHooks = {
create: function (target) {
var targetId = target.get(association.identifier);
if (targetId) {
return CounterUtil.increment(targetId);
}
},
update: function (target) {
var targetId = target.get(association.identifier)
, promises = [];
if (targetId && !previousTargetId) {
promises.push(CounterUtil.increment(targetId));
}
if (!targetId && previousTargetId) {
promises.push(CounterUtil.decrement(targetId));
}
if (previousTargetId && targetId && previousTargetId !== targetId) {
promises.push(CounterUtil.increment(targetId));
promises.push(CounterUtil.decrement(previousTargetId));
}
return Promise.all(promises);
},
destroy: function (target) {
var targetId = target.get(association.identifier);
if (targetId) {
return CounterUtil.decrement(targetId);
}
if (targetId) {
return CounterUtil.decrement(targetId);
}
};
// previousDataValues are cleared before afterUpdate, so we need to save this here
association.target.addHook('beforeUpdate', function (target) {
previousTargetId = target.previous(association.identifier);
});
if (this.options.atomic === false) {
association.target.addHook('afterCreate', fullUpdateHook);
association.target.addHook('afterUpdate', fullUpdateHook);
association.target.addHook('afterDestroy', fullUpdateHook);
} else {
association.target.addHook('afterCreate', atomicHooks.create);
association.target.addHook('afterUpdate', atomicHooks.update);
association.target.addHook('afterDestroy', atomicHooks.destroy);
}
};
return CounterCache;
})();
// previousDataValues are cleared before afterUpdate, so we need to save this here
association.target.addHook('beforeUpdate', function (target) {
previousTargetId = target.previous(association.identifier);
});
if (this.options.atomic === false) {
association.target.addHook('afterCreate', fullUpdateHook);
association.target.addHook('afterUpdate', fullUpdateHook);
association.target.addHook('afterDestroy', fullUpdateHook);
} else {
association.target.addHook('afterCreate', atomicHooks.create);
association.target.addHook('afterUpdate', atomicHooks.update);
association.target.addHook('afterDestroy', atomicHooks.destroy);
}
};
module.exports = CounterCache;
This diff could not be displayed because it is too large.
......@@ -3,7 +3,7 @@
var DataTypes = require('./data-types')
, SqlString = require('./sql-string')
, lodash = require('lodash')
, ParameterValidator = require('./utils/parameter-validator')
, parameterValidator = require('./utils/parameter-validator')
, inflection = require('inflection')
, dottie = require('dottie')
, uuid = require('node-uuid')
......@@ -398,9 +398,7 @@ var Utils = module.exports = {
this.logic = logic;
},
validateParameter: function(value, expectation, options) {
return ParameterValidator.check(value, expectation, options);
},
validateParameter: parameterValidator,
formatReferences: function (obj) {
if (!lodash.isPlainObject(obj.references)) {
......
......@@ -3,7 +3,7 @@
var _ = require('lodash');
var util = require('util');
var validateDeprecation = function(value, expectation, options) {
function validateDeprecation (value, expectation, options) {
if (!options.deprecated) {
return;
}
......@@ -17,9 +17,9 @@ var validateDeprecation = function(value, expectation, options) {
}
return valid;
};
}
var validate = function(value, expectation) {
function validate (value, expectation) {
// the second part of this check is a workaround to deal with an issue that occurs in node-webkit when
// using object literals. https://github.com/sequelize/sequelize/issues/2685
if (value instanceof expectation || Object.prototype.toString.call(value) === Object.prototype.toString.call(expectation.call())) {
......@@ -27,31 +27,31 @@ var validate = function(value, expectation) {
}
throw new Error(util.format('The parameter (value: %s) is no %s.', value, expectation.name));
};
module.exports = {
check: function(value, expectation, options) {
options = _.extend({
deprecated: false,
index: null,
method: null,
optional: false
}, options || {});
if (!value && options.optional) {
return true;
}
if (value === undefined) {
throw new Error('No value has been passed.');
}
if (expectation === undefined) {
throw new Error('No expectation has been passed.');
}
return false
|| validateDeprecation(value, expectation, options)
|| validate(value, expectation, options);
}
function check (value, expectation, options) {
options = _.extend({
deprecated: false,
index: null,
method: null,
optional: false
}, options || {});
if (!value && options.optional) {
return true;
}
if (value === undefined) {
throw new Error('No value has been passed.');
}
};
if (expectation === undefined) {
throw new Error('No expectation has been passed.');
}
return false
|| validateDeprecation(value, expectation, options)
|| validate(value, expectation, options);
}
module.exports = check;
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!