Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
public
/
sequelize
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
不要怂,就是干,撸起袖子干!
Commit 001b1567
authored
May 30, 2013
by
Sascha Depold
Browse files
Options
Browse Files
Download
Plain Diff
updated the validator to be async
2 parents
671718a5
41080488
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
138 additions
and
83 deletions
lib/dao-validator.js
lib/dao.js
lib/emitters/custom-event-emitter.js
spec/dao.validations.spec.js
lib/dao-validator.js
View file @
001b156
...
@@ -3,32 +3,52 @@ var Validator = require("validator")
...
@@ -3,32 +3,52 @@ var Validator = require("validator")
var
DaoValidator
=
module
.
exports
=
function
(
model
)
{
var
DaoValidator
=
module
.
exports
=
function
(
model
)
{
this
.
model
=
model
this
.
model
=
model
this
.
chainer
=
new
Utils
.
QueryChainer
()
}
}
DaoValidator
.
prototype
.
validate
=
function
()
{
DaoValidator
.
prototype
.
validate
=
function
()
{
return
new
Utils
.
CustomEventEmitter
(
function
(
emitter
)
{
validateAttributes
.
call
(
this
)
validateModel
.
call
(
this
)
this
.
chainer
.
run
()
.
success
(
function
()
{
emitter
.
emit
(
'success'
)
})
.
error
(
function
(
err
)
{
var
errors
=
{}
var
errors
=
{}
errors
=
Utils
.
_
.
extend
(
errors
,
validateAttributes
.
call
(
this
))
Utils
.
_
.
each
(
err
,
function
(
value
)
{
errors
=
Utils
.
_
.
extend
(
errors
,
validateModel
.
call
(
this
))
Utils
.
_
.
extend
(
errors
,
value
)
})
return
errors
emitter
.
emit
(
'success'
,
errors
)
})
}.
bind
(
this
)).
run
()
}
}
// private
// private
var
validateModel
=
function
()
{
var
validateModel
=
function
()
{
var
errors
=
{}
Utils
.
_
.
each
(
this
.
model
.
__options
.
validate
,
function
(
_validator
,
validatorType
)
{
var
validator
=
prepareValidationOfAttribute
.
call
(
this
,
undefined
,
_validator
,
validatorType
,
{
omitValue
:
true
})
// for each model validator for this DAO
Utils
.
_
.
each
(
this
.
model
.
__options
.
validate
,
function
(
validator
,
validatorType
)
{
this
.
chainer
.
add
(
new
Utils
.
CustomEventEmitter
(
function
(
emitter
)
{
try
{
var
next
=
function
(
err
)
{
validator
.
apply
(
this
.
model
)
if
(
err
)
{
}
catch
(
err
)
{
var
error
=
{}
errors
[
validatorType
]
=
[
err
.
message
]
// TODO: data structure needs to change for 2.0
error
[
validatorType
]
=
[
err
]
emitter
.
emit
(
'error'
,
error
)
}
else
{
emitter
.
emit
(
'success'
)
}
}
}
validator
.
args
.
unshift
(
next
);
validator
.
fn
.
apply
(
null
,
validator
.
args
)
}.
bind
(
this
)).
run
())
}.
bind
(
this
))
}.
bind
(
this
))
return
errors
}
}
var
validateAttributes
=
function
()
{
var
validateAttributes
=
function
()
{
...
@@ -48,32 +68,27 @@ var validateAttributes = function() {
...
@@ -48,32 +68,27 @@ var validateAttributes = function() {
}
}
var
validateAttribute
=
function
(
value
,
field
)
{
var
validateAttribute
=
function
(
value
,
field
)
{
var
errors
=
{}
// for each validator
// for each validator
Utils
.
_
.
each
(
this
.
model
.
validators
[
field
],
function
(
details
,
validatorType
)
{
Utils
.
_
.
each
(
this
.
model
.
validators
[
field
],
function
(
details
,
validatorType
)
{
var
validator
=
prepareValidationOfAttribute
.
call
(
this
,
value
,
details
,
validatorType
)
var
validator
=
prepareValidationOfAttribute
.
call
(
this
,
value
,
details
,
validatorType
)
t
ry
{
t
his
.
chainer
.
add
(
new
Utils
.
CustomEventEmitter
(
function
(
emitter
)
{
va
lidator
.
fn
.
apply
(
null
,
validator
.
args
)
va
r
next
=
function
(
err
)
{
}
catch
(
err
)
{
if
(
err
)
{
var
msg
=
err
.
message
var
error
=
{}
error
[
field
]
=
[
err
]
// if we didn't provide a custom error message then augment the default one returned by the validator
emitter
.
emit
(
'error'
,
error
)
if
(
!
validator
.
msg
&&
!
validator
.
isCustom
)
{
}
else
{
msg
+=
": "
+
field
emitter
.
emit
(
'success'
)
}
}
// each field can have multiple validation errors stored against it
errors
[
field
]
=
errors
[
field
]
||
[]
errors
[
field
].
push
(
msg
)
}
}
validator
.
args
.
unshift
(
next
);
validator
.
fn
.
apply
(
null
,
validator
.
args
)
}.
bind
(
this
)).
run
())
}.
bind
(
this
))
// for each validator for this field
}.
bind
(
this
))
// for each validator for this field
return
errors
}
}
var
prepareValidationOfAttribute
=
function
(
value
,
details
,
validatorType
)
{
var
prepareValidationOfAttribute
=
function
(
value
,
details
,
validatorType
,
options
)
{
var
isCustomValidator
=
false
// if true then it's a custom validation method
var
isCustomValidator
=
false
// if true then it's a custom validation method
,
validatorFunction
=
null
// the validation function to call
,
validatorFunction
=
null
// the validation function to call
,
validatorArgs
=
[]
// extra arguments to pass to validation function
,
validatorArgs
=
[]
// extra arguments to pass to validation function
...
@@ -82,7 +97,9 @@ var prepareValidationOfAttribute = function(value, details, validatorType) {
...
@@ -82,7 +97,9 @@ var prepareValidationOfAttribute = function(value, details, validatorType) {
if
(
typeof
details
===
'function'
)
{
if
(
typeof
details
===
'function'
)
{
// it is a custom validator function?
// it is a custom validator function?
isCustomValidator
=
true
isCustomValidator
=
true
validatorFunction
=
Utils
.
_
.
bind
(
details
,
this
.
model
,
value
)
validatorFunction
=
function
(
next
)
{
details
.
apply
(
this
.
model
,
((
options
||
{}).
omitValue
)
?
[
next
]
:
[
value
,
next
])
}.
bind
(
this
)
}
else
{
}
else
{
// it is a validator module function?
// it is a validator module function?
...
@@ -105,7 +122,16 @@ var prepareValidationOfAttribute = function(value, details, validatorType) {
...
@@ -105,7 +122,16 @@ var prepareValidationOfAttribute = function(value, details, validatorType) {
}
}
// bind to validator obj
// bind to validator obj
validatorFunction
=
Utils
.
_
.
bind
(
validator
[
validatorType
],
validator
)
validatorFunction
=
function
(
next
)
{
var
args
=
Array
.
prototype
.
slice
.
call
(
arguments
,
1
)
try
{
validator
[
validatorType
].
apply
(
validator
,
args
)
next
()
}
catch
(
err
)
{
next
(
err
.
message
)
}
}
}
}
return
{
return
{
...
...
lib/dao.js
View file @
001b156
...
@@ -148,15 +148,15 @@ module.exports = (function() {
...
@@ -148,15 +148,15 @@ module.exports = (function() {
this
.
dataValues
[
updatedAtAttr
]
=
values
[
updatedAtAttr
]
=
Utils
.
now
()
this
.
dataValues
[
updatedAtAttr
]
=
values
[
updatedAtAttr
]
=
Utils
.
now
()
}
}
var
errors
=
this
.
validate
()
if
(
!!
errors
)
{
return
new
Utils
.
CustomEventEmitter
(
function
(
emitter
)
{
return
new
Utils
.
CustomEventEmitter
(
function
(
emitter
)
{
this
.
validate
().
success
(
function
(
errors
)
{
if
(
!!
errors
)
{
emitter
.
emit
(
'error'
,
errors
)
emitter
.
emit
(
'error'
,
errors
)
}).
run
()
}
else
if
(
this
.
isNewRecord
)
{
}
this
else
if
(
this
.
isNewRecord
)
{
.
QueryInterface
return
this
.
QueryInterface
.
insert
(
this
,
this
.
QueryInterface
.
QueryGenerator
.
addSchema
(
this
.
__factory
),
values
)
.
insert
(
this
,
this
.
QueryInterface
.
QueryGenerator
.
addSchema
(
this
.
__factory
),
values
)
.
proxy
(
emitter
)
}
else
{
}
else
{
var
identifier
=
this
.
__options
.
hasPrimaryKeys
?
this
.
primaryKeyValues
:
this
.
id
;
var
identifier
=
this
.
__options
.
hasPrimaryKeys
?
this
.
primaryKeyValues
:
this
.
id
;
...
@@ -167,8 +167,10 @@ module.exports = (function() {
...
@@ -167,8 +167,10 @@ module.exports = (function() {
var
tableName
=
this
.
QueryInterface
.
QueryGenerator
.
addSchema
(
this
.
__factory
)
var
tableName
=
this
.
QueryInterface
.
QueryGenerator
.
addSchema
(
this
.
__factory
)
,
query
=
this
.
QueryInterface
.
update
(
this
,
tableName
,
values
,
identifier
)
,
query
=
this
.
QueryInterface
.
update
(
this
,
tableName
,
values
,
identifier
)
return
query
query
.
proxy
(
emitter
)
}
}
}.
bind
(
this
))
}.
bind
(
this
)).
run
()
}
}
/*
/*
...
@@ -209,13 +211,9 @@ module.exports = (function() {
...
@@ -209,13 +211,9 @@ module.exports = (function() {
* @return null if and only if validation successful; otherwise an object containing { field name : [error msgs] } entries.
* @return null if and only if validation successful; otherwise an object containing { field name : [error msgs] } entries.
*/
*/
DAO
.
prototype
.
validate
=
function
()
{
DAO
.
prototype
.
validate
=
function
()
{
var
validator
=
new
DaoValidator
(
this
)
return
new
DaoValidator
(
this
).
validate
()
,
errors
=
validator
.
validate
()
return
(
Utils
.
_
.
isEmpty
(
errors
)
?
null
:
errors
)
}
}
DAO
.
prototype
.
updateAttributes
=
function
(
updates
,
fields
)
{
DAO
.
prototype
.
updateAttributes
=
function
(
updates
,
fields
)
{
this
.
setAttributes
(
updates
)
this
.
setAttributes
(
updates
)
return
this
.
save
(
fields
)
return
this
.
save
(
fields
)
...
...
lib/emitters/custom-event-emitter.js
View file @
001b156
...
@@ -6,13 +6,13 @@ var util = require("util")
...
@@ -6,13 +6,13 @@ var util = require("util")
var
bindToProcess
=
function
(
fct
)
{
var
bindToProcess
=
function
(
fct
)
{
if
(
fct
)
{
if
(
fct
)
{
if
(
process
.
domain
)
{
if
(
process
.
domain
)
{
return
process
.
domain
.
bind
(
fct
);
return
process
.
domain
.
bind
(
fct
)
}
}
}
}
return
fct
;
return
fct
}
;
}
module
.
exports
=
(
function
()
{
module
.
exports
=
(
function
()
{
var
CustomEventEmitter
=
function
(
fct
)
{
var
CustomEventEmitter
=
function
(
fct
)
{
...
@@ -54,6 +54,7 @@ module.exports = (function() {
...
@@ -54,6 +54,7 @@ module.exports = (function() {
return
this
return
this
}
}
// emit the events on the foreign emitter once events got triggered for me
CustomEventEmitter
.
prototype
.
proxy
=
function
(
emitter
)
{
CustomEventEmitter
.
prototype
.
proxy
=
function
(
emitter
)
{
proxyEventKeys
.
forEach
(
function
(
eventKey
)
{
proxyEventKeys
.
forEach
(
function
(
eventKey
)
{
this
.
on
(
eventKey
,
function
(
result
)
{
this
.
on
(
eventKey
,
function
(
result
)
{
...
@@ -73,7 +74,5 @@ module.exports = (function() {
...
@@ -73,7 +74,5 @@ module.exports = (function() {
}).
then
(
onFulfilled
,
onRejected
)
}).
then
(
onFulfilled
,
onRejected
)
}
}
return
CustomEventEmitter
return
CustomEventEmitter
;
})()
})()
spec/dao.validations.spec.js
View file @
001b156
...
@@ -201,7 +201,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
...
@@ -201,7 +201,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
for
(
var
i
=
0
;
i
<
validatorDetails
.
fail
.
length
;
i
++
)
{
for
(
var
i
=
0
;
i
<
validatorDetails
.
fail
.
length
;
i
++
)
{
var
failingValue
=
validatorDetails
.
fail
[
i
]
var
failingValue
=
validatorDetails
.
fail
[
i
]
it
(
'correctly specifies an instance as invalid using a value of "'
+
failingValue
+
'" for the validation "'
+
validator
+
'"'
,
function
()
{
it
(
'correctly specifies an instance as invalid using a value of "'
+
failingValue
+
'" for the validation "'
+
validator
+
'"'
,
function
(
done
)
{
var
validations
=
{}
var
validations
=
{}
,
message
=
validator
+
"("
+
failingValue
+
")"
,
message
=
validator
+
"("
+
failingValue
+
")"
...
@@ -221,11 +221,15 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
...
@@ -221,11 +221,15 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
})
})
var
failingUser
=
UserFail
.
build
({
name
:
failingValue
})
var
failingUser
=
UserFail
.
build
({
name
:
failingValue
})
,
errors
=
failingUser
.
validate
()
,
errors
=
undefined
;
expect
(
errors
).
not
.
toBeNull
()
expect
(
errors
).
toEqual
({
name
:
[
message
]
})
failingUser
.
validate
().
done
(
function
(
err
,
_errors
)
{
})
expect
(
_errors
).
not
.
toBeNull
();
expect
(
_errors
).
toEqual
({
name
:
[
message
]
});
done
();
});
});
}
}
////////////////////////////
////////////////////////////
...
@@ -234,7 +238,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
...
@@ -234,7 +238,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
for
(
var
j
=
0
;
j
<
validatorDetails
.
pass
.
length
;
j
++
)
{
for
(
var
j
=
0
;
j
<
validatorDetails
.
pass
.
length
;
j
++
)
{
var
succeedingValue
=
validatorDetails
.
pass
[
j
]
var
succeedingValue
=
validatorDetails
.
pass
[
j
]
it
(
'correctly specifies an instance as valid using a value of "'
+
succeedingValue
+
'" for the validation "'
+
validator
+
'"'
,
function
()
{
it
(
'correctly specifies an instance as valid using a value of "'
+
succeedingValue
+
'" for the validation "'
+
validator
+
'"'
,
function
(
done
)
{
var
validations
=
{}
var
validations
=
{}
if
(
validatorDetails
.
hasOwnProperty
(
'spec'
))
{
if
(
validatorDetails
.
hasOwnProperty
(
'spec'
))
{
...
@@ -252,21 +256,30 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
...
@@ -252,21 +256,30 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
}
}
})
})
var
successfulUser
=
UserSuccess
.
build
({
name
:
succeedingValue
})
var
successfulUser
=
UserSuccess
.
build
({
name
:
succeedingValue
});
expect
(
successfulUser
.
validate
()).
toBeNull
()
successfulUser
.
validate
().
success
(
function
()
{
expect
(
arguments
.
length
).
toBe
(
0
);
done
();
}).
error
(
function
(
err
)
{
expect
(
err
).
toBe
({})
done
();
});
})
})
}
}
}
}
}
}
it
(
'correctly validates using custom validation methods'
,
function
()
{
it
(
'correctly validates using custom validation methods'
,
function
(
done
)
{
var
User
=
this
.
sequelize
.
define
(
'User'
+
Math
.
random
(),
{
var
User
=
this
.
sequelize
.
define
(
'User'
+
Math
.
random
(),
{
name
:
{
name
:
{
type
:
Sequelize
.
STRING
,
type
:
Sequelize
.
STRING
,
validate
:
{
validate
:
{
customFn
:
function
(
val
)
{
customFn
:
function
(
val
,
next
)
{
if
(
val
!==
"2"
)
{
if
(
val
!==
"2"
)
{
throw
new
Error
(
"name should equal '2'"
)
next
(
"name should equal '2'"
)
}
else
{
next
()
}
}
}
}
}
}
...
@@ -274,16 +287,23 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
...
@@ -274,16 +287,23 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
})
})
var
failingUser
=
User
.
build
({
name
:
"3"
})
var
failingUser
=
User
.
build
({
name
:
"3"
})
,
errors
=
failingUser
.
validate
()
expect
(
errors
).
not
.
toBeNull
(
null
)
failingUser
.
validate
().
error
(
function
(
errors
)
{
expect
(
errors
).
toEqual
({
name
:
[
"name should equal '2'"
]
})
expect
(
errors
).
toEqual
({
name
:
[
"name should equal '2'"
]
})
var
successfulUser
=
User
.
build
({
name
:
"2"
})
var
successfulUser
=
User
.
build
({
name
:
"2"
})
expect
(
successfulUser
.
validate
()).
toBeNull
()
successfulUser
.
validate
().
success
(
function
()
{
expect
(
arguments
.
length
).
toBe
(
0
);
done
();
}).
error
(
function
(
err
)
{
expect
(
err
).
toBe
({});
done
();
})
});
})
})
it
(
'skips other validations if allowNull is true and the value is null'
,
function
()
{
it
(
'skips other validations if allowNull is true and the value is null'
,
function
(
done
)
{
var
User
=
this
.
sequelize
.
define
(
'User'
+
Math
.
random
(),
{
var
User
=
this
.
sequelize
.
define
(
'User'
+
Math
.
random
(),
{
age
:
{
age
:
{
type
:
Sequelize
.
INTEGER
,
type
:
Sequelize
.
INTEGER
,
...
@@ -294,20 +314,22 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
...
@@ -294,20 +314,22 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
}
}
})
})
var
failingUser
=
User
.
build
({
age
:
-
1
})
User
,
errors
=
failingUser
.
validate
()
.
build
({
age
:
-
1
})
.
validate
()
.
success
(
function
(
errors
)
{
expect
(
errors
).
not
.
toBeNull
(
null
)
expect
(
errors
).
not
.
toBeNull
(
null
)
expect
(
errors
).
toEqual
({
age
:
[
'must be positive'
]
})
expect
(
errors
).
toEqual
({
age
:
[
'must be positive'
]
})
var
successfulUser1
=
User
.
build
({
age
:
null
})
User
.
build
({
age
:
null
}).
validate
().
success
(
function
()
{
expect
(
successfulUser1
.
validate
()).
toBeNull
()
User
.
build
({
age
:
1
}).
validate
().
success
(
function
()
{
done
()
var
successfulUser2
=
User
.
build
({
age
:
1
})
})
expect
(
successfulUser2
.
validate
()).
toBeNull
()
})
})
})
})
it
(
'validates a model with custom model-wide validation methods'
,
function
()
{
it
(
'validates a model with custom model-wide validation methods'
,
function
(
done
)
{
var
Foo
=
this
.
sequelize
.
define
(
'Foo'
+
Math
.
random
(),
{
var
Foo
=
this
.
sequelize
.
define
(
'Foo'
+
Math
.
random
(),
{
field1
:
{
field1
:
{
type
:
Sequelize
.
INTEGER
,
type
:
Sequelize
.
INTEGER
,
...
@@ -319,22 +341,32 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
...
@@ -319,22 +341,32 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
}
}
},
{
},
{
validate
:
{
validate
:
{
xnor
:
function
()
{
xnor
:
function
(
done
)
{
if
((
this
.
field1
===
null
)
===
(
this
.
field2
===
null
))
{
if
((
this
.
field1
===
null
)
===
(
this
.
field2
===
null
))
{
throw
new
Error
(
'xnor failed'
);
done
(
'xnor failed'
)
}
else
{
done
()
}
}
}
}
}
}
})
})
var
failingFoo
=
Foo
.
build
({
field1
:
null
,
field2
:
null
})
Foo
,
errors
=
failingFoo
.
validate
()
.
build
({
field1
:
null
,
field2
:
null
})
.
validate
()
.
success
(
function
(
errors
)
{
expect
(
errors
).
not
.
toBeNull
()
expect
(
errors
).
not
.
toBeNull
()
expect
(
errors
).
toEqual
({
'xnor'
:
[
'xnor failed'
]
})
expect
(
errors
).
toEqual
({
'xnor'
:
[
'xnor failed'
]
})
var
successfulFoo
=
Foo
.
build
({
field1
:
33
,
field2
:
null
})
Foo
expect
(
successfulFoo
.
validate
()).
toBeNull
()
.
build
({
field1
:
33
,
field2
:
null
})
.
validate
()
.
success
(
function
(
errors
)
{
console
.
log
(
errors
)
expect
(
errors
).
not
.
toBeDefined
()
done
()
})
})
})
})
})
})
})
})
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment