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

Commit 1ef192b9 by Mick Hansen

refactor(data-types): data types should always be functions, data types should a…

…lways be inited before use
1 parent 8d7c0703
......@@ -249,7 +249,7 @@ module.exports = (function() {
var template = "<%= type %>"
, replacements = { type: dataType.type };
if (dataType.type.toString() === DataTypes.ENUM.toString()) {
if (dataType.type instanceof DataTypes.ENUM) {
replacements.type = "TEXT";
if (!(Array.isArray(dataType.values) && (dataType.values.length > 0))) {
......
......@@ -368,7 +368,7 @@ InstanceValidator.prototype._validateSchema = function(rawAttribute, field, valu
this.errors.push(error);
}
if (rawAttribute.type === DataTypes.STRING || rawAttribute.type instanceof DataTypes.STRING || rawAttribute.type === DataTypes.TEXT) {
if (rawAttribute.type === DataTypes.STRING || rawAttribute.type instanceof DataTypes.STRING || rawAttribute.type === DataTypes.TEXT || rawAttribute.type instanceof DataTypes.TEXT) {
if (Array.isArray(value) || (_.isObject(value) && !value._isSequelizeMethod) && !Buffer.isBuffer(value)) {
error = new sequelizeError.ValidationErrorItem(field + ' cannot be an array or an object', 'string violation', field, value);
this.errors.push(error);
......
......@@ -81,22 +81,23 @@ module.exports = (function() {
throw new Error('Unrecognized data type for field ' + name);
}
if (attribute.type.toString() === DataTypes.ENUM.toString()) {
if (typeof attribute.type === "function") attribute.type = new attribute.type();
if (attribute.type instanceof DataTypes.ENUM) {
// The ENUM is a special case where the type is an object containing the values
attribute.values = attribute.type.values || attribute.values || [];
attribute.values = attribute.values || attribute.type.values || [];
if (!attribute.values.length) {
throw new Error('Values for ENUM haven\'t been defined.');
}
attributes[name].validate = attributes[name].validate || {
attribute.validate = attribute.validate || {
_checkEnum: function(value, next) {
var hasValue = value !== undefined
, isMySQL = ['mysql', 'mariadb'].indexOf(options.sequelize.options.dialect) !== -1
, ciCollation = !!options.collate && options.collate.match(/_ci$/i) !== null
, valueOutOfScope;
if (isMySQL && ciCollation && hasValue) {
var scopeIndex = (attributes[name].values || []).map(function(d) { return d.toLowerCase(); }).indexOf(value.toLowerCase());
valueOutOfScope = scopeIndex === -1;
......@@ -290,7 +291,7 @@ module.exports = (function() {
this.Instance.prototype.validators = {};
Utils._.each(this.rawAttributes, function(definition, name) {
var type = definition.type._typeName || definition.type;
if (typeof definition.type === "function") definition.type = new definition.type();
definition.Model = self;
definition.fieldName = name;
......@@ -300,21 +301,28 @@ module.exports = (function() {
definition.field = name;
}
if (type === DataTypes.BOOLEAN) {
if (definition.type instanceof DataTypes.BOOLEAN) {
self._booleanAttributes.push(name);
} else if (type === DataTypes.DATE) {
} else if (definition.type instanceof DataTypes.DATE) {
self._dateAttributes.push(name);
} else if (type === DataTypes.HSTORE) {
} else if (definition.type instanceof DataTypes.HSTORE) {
self._hstoreAttributes.push(name);
} else if (type === DataTypes.JSON) {
} else if (definition.type instanceof DataTypes.JSON) {
self._jsonAttributes.push(name);
} else if (type === DataTypes.VIRTUAL) {
} else if (definition.type instanceof DataTypes.VIRTUAL) {
self._virtualAttributes.push(name);
}
if (definition.hasOwnProperty('defaultValue')) {
self._defaultValues[name] = Utils._.partial(
Utils.toDefaultValue, definition.defaultValue);
if (typeof definition.defaultValue === "function" && (
definition.defaultValue === DataTypes.NOW ||
definition.defaultValue === DataTypes.UUIDV4 ||
definition.defaultValue === DataTypes.UUIDV4
)) {
definition.defaultValue = new definition.defaultValue();
}
self._defaultValues[name] = Utils._.partial(Utils.toDefaultValue, definition.defaultValue);
}
if (definition.hasOwnProperty('validate')) {
......@@ -808,12 +816,12 @@ module.exports = (function() {
options.dataType = this.rawAttributes[field].type;
} else {
// Use FLOAT as fallback
options.dataType = DataTypes.FLOAT;
options.dataType = new DataTypes.FLOAT();
}
}
options = paranoidClause(this, options);
return this.QueryInterface.rawSelect(this.getTableName(options), options, aggregateFunction, this);
};
......
......@@ -80,6 +80,27 @@ module.exports = (function() {
attribute = { type: attribute, allowNull: true };
}
if (typeof attribute.type === "function") attribute.type = new attribute.type();
if (attribute.hasOwnProperty('defaultValue')) {
if (typeof attribute.defaultValue === "function" && (
attribute.defaultValue === DataTypes.NOW ||
attribute.defaultValue === DataTypes.UUIDV4 ||
attribute.defaultValue === DataTypes.UUIDV4
)) {
attribute.defaultValue = new definition.defaultValue();
}
}
if (attribute.type instanceof DataTypes.ENUM) {
// The ENUM is a special case where the type is an object containing the values
attribute.values = attribute.values || attribute.type.values || [];
if (!attribute.values.length) {
throw new Error('Values for ENUM haven\'t been defined.');
}
}
return attribute;
});
......@@ -330,8 +351,9 @@ module.exports = (function() {
});
};
QueryInterface.prototype.addColumn = function(table, key, dataType) {
return this.sequelize.query(this.QueryGenerator.addColumnQuery(table, key, dataType), null, {logging: this.sequelize.options.logging});
QueryInterface.prototype.addColumn = function(table, key, attribute) {
if (typeof attribute.type === "function") attribute.type = new attribute.type();
return this.sequelize.query(this.QueryGenerator.addColumnQuery(table, key, attribute), null, {logging: this.sequelize.options.logging});
};
QueryInterface.prototype.removeColumn = function(tableName, attributeName) {
......@@ -353,6 +375,8 @@ module.exports = (function() {
attributes[attributeName] = dataTypeOrOptions;
}
if (typeof attributes[attributeName].type === "function") attributes[attributeName].type = new attributes[attributeName].type();
if (this.sequelize.options.dialect === 'sqlite') {
// sqlite needs some special treatment as it cannot change a column
return SQLiteQueryInterface.changeColumn.call(this, tableName, attributes);
......@@ -741,13 +765,13 @@ module.exports = (function() {
if (dataType instanceof DataTypes.DECIMAL || dataType instanceof DataTypes.FLOAT) {
result = parseFloat(result);
} else if (dataType === DataTypes.INTEGER || dataType instanceof DataTypes.BIGINT) {
} else if (dataType instanceof DataTypes.INTEGER || dataType instanceof DataTypes.BIGINT) {
result = parseInt(result, 10);
} else if (dataType === DataTypes.DATE) {
} else if (dataType instanceof DataTypes.DATE) {
if (!Utils._.isDate(result)) {
result = new Date(result);
}
} else if (dataType === DataTypes.STRING) {
} else if (dataType instanceof DataTypes.STRING) {
// Nothing to do, result is already a string.
}
}
......
......@@ -473,11 +473,11 @@ var Utils = module.exports = {
toDefaultValue: function(value) {
if (lodash.isFunction(value)) {
return value();
} else if (value === DataTypes.UUIDV1) {
} else if (value instanceof DataTypes.UUIDV1) {
return uuid.v1();
} else if (value === DataTypes.UUIDV4) {
} else if (value instanceof DataTypes.UUIDV4) {
return uuid.v4();
} else if (value === DataTypes.NOW) {
} else if (value instanceof DataTypes.NOW) {
return Utils.now();
} else {
return value;
......@@ -496,9 +496,9 @@ var Utils = module.exports = {
// TODO this will be schemable when all supported db
// have been normalized for this case
if (value === DataTypes.NOW) { return false; }
if (value instanceof DataTypes.NOW) { return false; }
if (value === DataTypes.UUIDV1 || value === DataTypes.UUIDV4) { return false; }
if (value instanceof DataTypes.UUIDV1 || value instanceof DataTypes.UUIDV4) { return false; }
if (lodash.isFunction(value)) {
return false;
......
......@@ -580,7 +580,7 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() {
User.belongsTo(Group);
self.sequelize.sync({ force: true }).success(function() {
expect(User.rawAttributes.GroupPKBTName.type.toString()).to.equal(DataTypes.STRING.toString());
expect(User.rawAttributes.GroupPKBTName.type.toString()).to.equal(DataTypes.STRING().toString());
done();
});
});
......@@ -604,7 +604,7 @@ describe(Support.getTestDialectTeaser('BelongsTo'), function() {
.success(function() {
dataTypes.forEach(function(dataType, i) {
expect(Tasks[dataType].rawAttributes.userId.type.toString())
.to.equal(dataType.toString());
.to.equal(dataType().toString());
if ((i + 1) === dataTypes.length) {
done();
......
......@@ -2607,7 +2607,7 @@ describe(Support.getTestDialectTeaser('HasMany'), function() {
User.hasMany(Tasks[dataType], { foreignKey: 'userId', keyType: dataType, constraints: false });
return Tasks[dataType].sync({ force: true }).then(function() {
expect(Tasks[dataType].rawAttributes.userId.type.toString()).to.equal(dataType.toString());
expect(Tasks[dataType].rawAttributes.userId.type instanceof dataType).to.be.ok;
});
});
});
......@@ -2624,7 +2624,7 @@ describe(Support.getTestDialectTeaser('HasMany'), function() {
User.hasMany(Task);
return this.sequelize.sync({ force: true }).then(function() {
expect(Task.rawAttributes.UserId.type).to.equal(DataTypes.STRING);
expect(Task.rawAttributes.UserId.type instanceof DataTypes.STRING).to.be.ok;
});
});
......
......@@ -515,7 +515,7 @@ describe(Support.getTestDialectTeaser('HasOne'), function() {
Group.hasOne(User);
self.sequelize.sync({ force: true }).success(function() {
expect(User.rawAttributes.GroupPKBTName.type.toString()).to.equal(Sequelize.STRING.toString());
expect(User.rawAttributes.GroupPKBTName.type.toString()).to.equal(Sequelize.STRING().toString());
done();
});
});
......@@ -536,7 +536,7 @@ describe(Support.getTestDialectTeaser('HasOne'), function() {
Tasks[dataType].sync({ force: true }).success(function() {
expect(Tasks[dataType].rawAttributes.userId.type.toString())
.to.equal(dataType.toString());
.to.equal(dataType().toString());
dataTypes.splice(dataTypes.indexOf(dataType), 1);
if (!dataTypes.length) {
......
......@@ -70,15 +70,16 @@ describe(Support.getTestDialectTeaser('DataTypes'), function() {
[Sequelize.BLOB('tiny'), 'BLOB(\'tiny\')', 'TINYBLOB'],
[Sequelize.BLOB('medium'), 'BLOB(\'medium\')', 'MEDIUMBLOB'],
[Sequelize.BLOB('long'), 'BLOB(\'long\')', 'LONGBLOB'],
[Sequelize.INTEGER, 'INTEGER', 'INTEGER'],
[Sequelize.INTEGER.UNSIGNED, 'INTEGER.UNSIGNED', 'INTEGER UNSIGNED'],
[Sequelize.INTEGER.UNSIGNED.ZEROFILL, 'INTEGER.UNSIGNED', 'INTEGER UNSIGNED ZEROFILL'],
[Sequelize.INTEGER(11), 'INTEGER(11)', 'INTEGER(11)'],
[Sequelize.INTEGER(11).UNSIGNED, 'INTEGER(11).UNSIGNED', 'INTEGER(11) UNSIGNED'],
[Sequelize.INTEGER(11).UNSIGNED.ZEROFILL, 'INTEGER(11).UNSIGNED.ZEROFILL', 'INTEGER(11) UNSIGNED ZEROFILL'],
[Sequelize.INTEGER(11).ZEROFILL, 'INTEGER(11).ZEROFILL', 'INTEGER(11) ZEROFILL'],
[Sequelize.INTEGER(11).ZEROFILL.UNSIGNED, 'INTEGER(11).ZEROFILL.UNSIGNED', 'INTEGER(11) UNSIGNED ZEROFILL'],
[Sequelize.BIGINT, 'BIGINT', 'BIGINT'],
[Sequelize.BIGINT.UNSIGNED, 'BIGINT.UNSIGNED', 'BIGINT UNSIGNED'],
[Sequelize.BIGINT(11), 'BIGINT(11)', 'BIGINT(11)'],
......@@ -124,7 +125,8 @@ describe(Support.getTestDialectTeaser('DataTypes'), function() {
}
}
expect(test[0].toString()).to.equal(test[2]);
if (typeof test[0] === "function") test[0] = new test[0]();
expect(test[0].toSql()).to.equal(test[2]);
done();
});
});
......
......@@ -908,8 +908,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
results.forEach(function(book, index) {
expect(book.title).to.equal(data.title);
expect(book.author).to.equal(data.author);
expect(books[index].rawAttributes.id.type.toString())
.to.equal(dataTypes[index].toString());
expect(books[index].rawAttributes.id.type instanceof dataTypes[index]).to.be.ok;
});
done();
});
......
......@@ -18,7 +18,7 @@ describe(Support.getTestDialectTeaser('CounterCache'), function() {
User.hasMany(Group, { counterCache: true });
expect(Object.keys(User.attributes)).to.contain('countGroups');
expect(User.attributes.countGroups.type).to.equal(DataTypes.INTEGER);
expect(User.attributes.countGroups.type instanceof DataTypes.INTEGER).to.be.ok;
});
it('supports `as`', function() {
......
......@@ -834,7 +834,11 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
Object.keys(customAttributes).forEach(function(attribute) {
Object.keys(customAttributes[attribute]).forEach(function(option) {
var optionValue = customAttributes[attribute][option];
expect(Picture.rawAttributes[attribute][option]).to.be.equal(optionValue);
if (typeof optionValue === "function" && optionValue() instanceof DataTypes.ABSTRACT) {
expect(Picture.rawAttributes[attribute][option] instanceof optionValue).to.be.ok;
} else {
expect(Picture.rawAttributes[attribute][option]).to.be.equal(optionValue);
}
});
});
done();
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!