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

Commit 4a181127 by Sascha Depold

validate integrity of enums

1 parent 5fe9b51a
...@@ -59,7 +59,7 @@ A very basic roadmap. Chances aren't too bad, that not mentioned things are impl ...@@ -59,7 +59,7 @@ A very basic roadmap. Chances aren't too bad, that not mentioned things are impl
### 1.8.0 ### 1.8.0
- API sugar (like Model.select().where().group().include().all()) - API sugar (like Model.select().where().group().include().all())
- Schema dumping - Schema dumping
- enum support - ~~enum support~~
- attributes / values of a dao instance should be scoped - attributes / values of a dao instance should be scoped
### 2.0.0 ### 2.0.0
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
- [DEPENDENCIES] mysql is now an optional dependency. #355 (thanks to clkao) - [DEPENDENCIES] mysql is now an optional dependency. #355 (thanks to clkao)
- [REFACTORING] separated tests for dialects - [REFACTORING] separated tests for dialects
- [REFACTORING] reduced number of sql queries used for adding an element to a N:M association. #449 (thanks to innofluence/janmeier) - [REFACTORING] reduced number of sql queries used for adding an element to a N:M association. #449 (thanks to innofluence/janmeier)
- [REFACTORING] dropped support for synchronous migrations. added third parameter which needs to get called once the migration has been finished. - [REFACTORING] dropped support for synchronous migrations. added third parameter which needs to get called once the migration has been finished. also this adds support for asynchronous actions in migrations.
- [OTHERS] code was formatted to fit the latest code style guidelines (thanks to durango) - [OTHERS] code was formatted to fit the latest code style guidelines (thanks to durango)
- [OTHERS] Explicitly target ./docs folder for generate-docs script. #444 (thanks to carsondarling) - [OTHERS] Explicitly target ./docs folder for generate-docs script. #444 (thanks to carsondarling)
- [BUG] fixed wrong version in sequelize binary - [BUG] fixed wrong version in sequelize binary
......
...@@ -362,7 +362,9 @@ module.exports = (function() { ...@@ -362,7 +362,9 @@ module.exports = (function() {
var self = this var self = this
, instance = new this.DAO(values, this.options, options.isNewRecord) , instance = new this.DAO(values, this.options, options.isNewRecord)
instance.isNewRecord = options.isNewRecord instance.isNewRecord = options.isNewRecord
instance.daoFactoryName = this.name
instance.daoFactory = this
return instance return instance
} }
......
...@@ -270,7 +270,9 @@ module.exports = (function() { ...@@ -270,7 +270,9 @@ module.exports = (function() {
var self = this var self = this
, instance = new this.DAO(values, this.options, options.isNewRecord) , instance = new this.DAO(values, this.options, options.isNewRecord)
instance.isNewRecord = options.isNewRecord instance.isNewRecord = options.isNewRecord
instance.daoFactoryName = this.name
instance.daoFactory = this
return instance return instance
} }
......
...@@ -108,6 +108,7 @@ module.exports = (function() { ...@@ -108,6 +108,7 @@ module.exports = (function() {
fields.push(createdAtAttr) fields.push(createdAtAttr)
} }
} }
fields.forEach(function(field) { fields.forEach(function(field) {
if (self.values[field] !== undefined) { if (self.values[field] !== undefined) {
values[field] = self.values[field] values[field] = self.values[field]
...@@ -115,6 +116,19 @@ module.exports = (function() { ...@@ -115,6 +116,19 @@ module.exports = (function() {
}) })
} }
for (var attrName in this.daoFactory.rawAttributes) {
if (this.daoFactory.rawAttributes.hasOwnProperty(attrName)) {
var definition = this.daoFactory.rawAttributes[attrName]
, isEnum = (definition.type === 'ENUM')
, hasValue = (typeof values[attrName] !== 'undefined')
, valueOutOfScope = (definition.values.indexOf(values[attrName]) === -1)
if (isEnum && hasValue && valueOutOfScope) {
throw new Error('Value "' + values[attrName] + '" for ENUM ' + attrName + ' is out of allowed scope. Allowed values: ' + definition.values.join(', '))
}
}
}
if (this.__options.timestamps && this.hasOwnProperty(updatedAtAttr)) { if (this.__options.timestamps && this.hasOwnProperty(updatedAtAttr)) {
this[updatedAtAttr] = values[updatedAtAttr] = new Date() this[updatedAtAttr] = values[updatedAtAttr] = new Date()
} }
......
...@@ -378,10 +378,14 @@ module.exports = (function() { ...@@ -378,10 +378,14 @@ module.exports = (function() {
var template = "<%= type %>" var template = "<%= type %>"
, replacements = { type: dataType.type } , replacements = { type: dataType.type }
if (dataType.type === DataTypes.ENUM && Array.isArray(dataType.values) && dataType.values.length > 0) { if (dataType.type === DataTypes.ENUM) {
replacements.type = "ENUM(" + Utils._.map(dataType.values, function(value) { if (Array.isArray(dataType.values) && (dataType.values.length > 0)) {
return Utils.escape(value) replacements.type = "ENUM(" + Utils._.map(dataType.values, function(value) {
}).join(", ") + ")" return Utils.escape(value)
}).join(", ") + ")"
} else {
throw new Error('Values for ENUM haven\'t been defined.')
}
} }
if (dataType.hasOwnProperty('allowNull') && (!dataType.allowNull)) { if (dataType.hasOwnProperty('allowNull') && (!dataType.allowNull)) {
......
...@@ -518,10 +518,14 @@ module.exports = (function() { ...@@ -518,10 +518,14 @@ module.exports = (function() {
var template = "<%= type %>" var template = "<%= type %>"
, replacements = { type: dataType.type } , replacements = { type: dataType.type }
if (dataType.type === DataTypes.ENUM && Array.isArray(dataType.values) && dataType.values.length > 0) { if (dataType.type === DataTypes.ENUM) {
replacements.type = "ENUM(" + Utils._.map(dataType.values, function(value) { if (Array.isArray(dataType.values) && (dataType.values.length > 0)) {
return Utils.escape(value) replacements.type = "ENUM(" + Utils._.map(dataType.values, function(value) {
}).join(", ") + ")" return Utils.escape(value)
}).join(", ") + ")"
} else {
throw new Error('Values for ENUM haven\'t been defined.')
}
} }
if (dataType.type === "TINYINT(1)") { if (dataType.type === "TINYINT(1)") {
......
...@@ -143,6 +143,14 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -143,6 +143,14 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
this.Review.sync({ force: true }).success(done) this.Review.sync({ force: true }).success(done)
}) })
it('=>raises an error if no values are defined', function() {
Helpers.assertException(function() {
this.sequelize.define('omnomnom', {
bla: { type: Helpers.Sequelize.ENUM }
})
}.bind(this), 'Values for ENUM haven\'t been defined.')
})
it('correctly stores values', function(done) { it('correctly stores values', function(done) {
this.Review.create({ status: 'active' }).success(function(review) { this.Review.create({ status: 'active' }).success(function(review) {
expect(review.status).toEqual('active') expect(review.status).toEqual('active')
...@@ -159,11 +167,10 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -159,11 +167,10 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
}.bind(this)) }.bind(this))
}) })
it("//doesn't save an instance if value is not in the range of enums", function(done) { it("=>doesn't save an instance if value is not in the range of enums", function() {
this.Review.create({ status: 'fnord' }).error(function(err) { Helpers.assertException(function() {
expect(1).toEqual(1) this.Review.create({ status: 'fnord' })
done() }.bind(this), 'Value "fnord" for ENUM status is out of allowed scope. Allowed values: scheduled, active, finished')
})
}) })
}) })
}) })
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!