-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add default validation based on attribute type #3472
Add default validation based on attribute type #3472
Conversation
Definitely! Schema inferred validations is something we've talked about previously that we'd like to do. |
However like with the allowNull schema validator we might get some complaints that the error messages aren't customizable. |
@@ -61,6 +61,10 @@ SqlString.escape = function(val, stringifyObjects, timeZone, dialect, field) { | |||
return val + ''; | |||
} | |||
|
|||
if (field && field.type && field.type.validate) { | |||
field.type.validate(val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this should be part of the validator codebase instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I feel this would fit better in built in validators
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the best place to put this without losing the type validation when performing queries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fixe You mean all non instance-create/update queries? Not sure, instance-validator wouldn't be enough certainly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm talking about every type of query that can be generated by Sequelize. Since we already know the data type of the columns that we are querying we can prevent an error from being thrown by the database.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping @mickhansen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps in query-generator.escape?
Not much better, but at least the qg is our own code, whereas sql-string is adapted from https://www.npmjs.com/package/sql-string so we might want to keep that as free of external modifications as possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My original take at this was exactly in that method but it's being overridden in postgres dialect. Suggestions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, no, not really sure I can come up with better suggestions then :)
Nice +1 |
885bb8d
to
a83ecd2
Compare
@fixe Are you still going to fix the existing issues? I really like your proposal and if you do not have the time to finish it, I'd volunteer, even though I'd prefer you finishing the PR. |
@BridgeAR: still unsure what's missing. @mickhansen if I fix the outstanding issues will you guys merge this? |
Let me know :-) |
I think we should move the validate call to And as mick said, I think type validation should also be called in the validation step https://github.com/sequelize/sequelize/blob/master/lib/instance-validator.js#L189 So: move validate to escape, add validate to instance-validator, and add some tests that calling If you can come up with an awesome way to let users specify custom messages for the validations that'd be awesome, but if not thats fine and we can defer that to later :) |
a83ecd2
to
a3b11be
Compare
Ping @fixe: Do you think you can finish this this week? I need this soon, since I had some issues today because of the missing validation. |
@BridgeAR impossible -- drowned this week, sorry. |
Ok thx |
This fixes #1431 |
a3b11be
to
c62bafa
Compare
@janmeier: I have updated the PR by moving the code from sql string to the query generator. I need feedback in some validators (returning true for now). |
@@ -376,6 +440,9 @@ var HSTORE = function() { | |||
util.inherits(HSTORE, ABSTRACT); | |||
|
|||
HSTORE.prototype.key = HSTORE.key = 'HSTORE'; | |||
HSTORE.prototype.validate = function(value) { | |||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_.isPlainObject
and maybe check that it is not more than one level deep
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you suggest to check for more than one level deep here?
Ping @fixe |
c62bafa
to
73c0b70
Compare
@janmeier implemented your suggestions and added some tests. Take a look. |
test('should throw an error if `value` is invalid', function() { | ||
var type = DataTypes.STRING(); | ||
|
||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expect(function () {
type.validate(12345);
}).to.throw(Sequelize.ValidationError, '12345 is not a valid string');
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same applies for the other tests
Hmm, for some reason this is failing miserably for postgres - Most of the errors seem to come from Do you need help on this @fixe or can you debug yourself? |
73c0b70
to
49d4a7c
Compare
@janmeier the thing is that enums are being created in a way that the data type don't have access to values: owner_type: { type: DataTypes.ENUM, values: ['user', 'org'], defaultValue: 'user', unique: 'combiIndex' } In order for the validation to work the following must be done: owner_type: { type: DataTypes.ENUM({ values: ['user', 'org'] }), defaultValue: 'user', unique: 'combiIndex' } WDYT? |
b969f47
to
a243a82
Compare
@janmeier PR updated, can you guys port this to other dialects? |
@fixe I can sure give it a try :) |
@@ -406,7 +406,7 @@ QueryInterface.prototype.renameColumn = function(tableName, attrNameBefore, attr | |||
|
|||
_options[attrNameAfter] = { | |||
attribute: attrNameAfter, | |||
type: data.type, | |||
type: DataTypes[data.type], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fixe This was breaking a mysql test so I removed it. Tests seem to pass fine without this change
…tion Add default validation based on attribute type
👍 |
Good work @fixe ! |
@@ -317,6 +368,13 @@ BOOLEAN.prototype.key = BOOLEAN.key = 'BOOLEAN'; | |||
BOOLEAN.prototype.toSql = function() { | |||
return 'TINYINT(1)'; | |||
}; | |||
BOOLEAN.prototype.validate = function(value) { | |||
if (!_.isBoolean(value)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I vote for using Validator.isBoolean()
, _.isBoolean()
is too strict even the value is number 1 or 0
Hello guys, Maybe I'm missing something here, but suppose we have one model with an integer attribute, with values from 1000 to 2000 in the database. My need is to search for all the rows that begin with '10'. In order for this to work, I would need to disable the type validation for queries. Am I wrong? Thanks in advance! |
+1 for @franciscotfmc comment |
3 similar comments
+1 for @franciscotfmc comment |
+1 for @franciscotfmc comment |
+1 for @franciscotfmc comment |
@franciscocardoso gte 1000 lt 1100? |
Hi, @mickhansen, I believe you were trying to ping @franciscotfmc. |
@franciscocardoso I was, sorry about that, the github auto complete is not entirely context aware apparently :) |
@mickhansen the case is that the query I'm about to execute comes from an input in the browser. The user can type pretty much anything and I need to search in a bunch of fields, including the integer type, checking if its value starts with '10'. The user can even type something like '10 abcd'. |
@franciscocardoso So you just throw whatever input and try to LIKE match it against all fields? |
Basically that, @mickhansen. This is one of those screens with only one search input and a list of results. I don't think that using multiple inputs would be very friendly in my case, so that I could use gte and lt as you said. Picture the facebook search as an example. There you can type a profile name or a phone number. If something contains my typed query, it'll show up. |
Wrong handle again @mickhansen. |
@franciscocardoso Oh god you must hate me by now. |
That's ok @mickhansen , no worries. |
We were thinking about adding a validation error to prevent database errors from being thrown since we already know the type before performing the query.
This is immensely useful with PostgreSQL to stop malformed queries from reaching the database.
@janmeier is this something that you guys are willing to merge? If so I can add some test cases.