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 ec4f8ef7
authored
May 23, 2013
by
durango
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #538 from iamjochem/feature/doaGettersAndSetters
Added DOA Getters and Setters
2 parents
41c1b6ae
b335eaa1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
184 additions
and
34 deletions
lib/dao-factory.js
lib/dao.js
spec/dao-factory.spec.js
lib/dao-factory.js
View file @
ec4f8ef
...
@@ -75,11 +75,33 @@ module.exports = (function() {
...
@@ -75,11 +75,33 @@ module.exports = (function() {
Util
.
inherits
(
this
.
DAO
,
DAO
);
Util
.
inherits
(
this
.
DAO
,
DAO
);
this
.
DAO
.
prototype
.
rawAttributes
=
this
.
rawAttributes
;
this
.
DAO
.
prototype
.
rawAttributes
=
this
.
rawAttributes
;
if
(
this
.
options
.
instanceMethods
)
{
if
(
this
.
options
.
instanceMethods
)
{
Utils
.
_
.
each
(
this
.
options
.
instanceMethods
,
function
(
fct
,
name
)
{
Utils
.
_
.
each
(
this
.
options
.
instanceMethods
,
function
(
fct
,
name
)
{
self
.
DAO
.
prototype
[
name
]
=
fct
self
.
DAO
.
prototype
[
name
]
=
fct
})
})
}
}
Utils
.
_
.
each
([
'Get'
,
'Set'
],
function
(
type
)
{
var
prop
=
type
.
toLowerCase
(),
opt
=
prop
+
'terMethods'
,
meth
=
'__define'
+
type
+
'ter__'
,
funcs
=
Utils
.
_
.
isObject
(
self
.
options
[
opt
])
?
self
.
options
[
opt
]
:
{}
;
Utils
.
_
.
each
(
self
.
rawAttributes
,
function
(
attr
,
name
)
{
if
(
attr
.
hasOwnProperty
(
prop
))
funcs
[
name
]
=
attr
[
prop
]
});
Utils
.
_
.
each
(
funcs
,
function
(
fct
,
name
)
{
if
(
!
Utils
.
_
.
isFunction
(
fct
))
throw
new
Error
(
type
+
'ter for "'
+
name
+
'" is not a function.'
)
self
.
DAO
.
prototype
[
meth
](
name
,
fct
);
})
})
this
.
DAO
.
prototype
.
attributes
=
Object
.
keys
(
this
.
DAO
.
prototype
.
rawAttributes
);
this
.
DAO
.
prototype
.
attributes
=
Object
.
keys
(
this
.
DAO
.
prototype
.
rawAttributes
);
this
.
DAO
.
prototype
.
booleanValues
=
[];
this
.
DAO
.
prototype
.
booleanValues
=
[];
...
...
lib/dao.js
View file @
ec4f8ef
...
@@ -7,28 +7,15 @@ module.exports = (function() {
...
@@ -7,28 +7,15 @@ module.exports = (function() {
var
DAO
=
function
(
values
,
options
,
isNewRecord
)
{
var
DAO
=
function
(
values
,
options
,
isNewRecord
)
{
var
self
=
this
var
self
=
this
this
.
dataValues
=
{}
this
.
__options
=
options
this
.
__options
=
options
this
.
hasPrimaryKeys
=
options
.
hasPrimaryKeys
this
.
hasPrimaryKeys
=
options
.
hasPrimaryKeys
this
.
selectedValues
=
values
this
.
selectedValues
=
values
this
.
__eagerlyLoadedAssociations
=
[]
this
.
__eagerlyLoadedAssociations
=
[]
initAttributes
.
call
(
this
,
values
,
isNewRecord
)
initAttributes
.
call
(
this
,
values
,
isNewRecord
)
if
(
this
.
hasDefaultValues
)
{
Utils
.
_
.
each
(
this
.
defaultValues
,
function
(
value
,
name
)
{
if
(
typeof
self
[
name
]
===
'undefined'
)
{
self
.
addAttribute
(
name
,
value
());
}
})
}
if
(
this
.
booleanValues
.
length
)
{
this
.
booleanValues
.
forEach
(
function
(
name
)
{
//transform integer 0,1 into boolean
self
[
name
]
=
!!
self
[
name
];
});
}
}
}
Utils
.
_
.
extend
(
DAO
.
prototype
,
Mixin
.
prototype
)
Utils
.
_
.
extend
(
DAO
.
prototype
,
Mixin
.
prototype
)
Object
.
defineProperty
(
DAO
.
prototype
,
'sequelize'
,
{
Object
.
defineProperty
(
DAO
.
prototype
,
'sequelize'
,
{
...
@@ -42,7 +29,7 @@ module.exports = (function() {
...
@@ -42,7 +29,7 @@ module.exports = (function() {
Object
.
defineProperty
(
DAO
.
prototype
,
'isDeleted'
,
{
Object
.
defineProperty
(
DAO
.
prototype
,
'isDeleted'
,
{
get
:
function
()
{
get
:
function
()
{
var
result
=
this
.
__options
.
timestamps
&&
this
.
__options
.
paranoid
var
result
=
this
.
__options
.
timestamps
&&
this
.
__options
.
paranoid
result
=
result
&&
this
[
this
.
__options
.
underscored
?
'deleted_at'
:
'deletedAt'
]
!==
null
result
=
result
&&
this
.
dataValues
[
this
.
__options
.
underscored
?
'deleted_at'
:
'deletedAt'
]
!==
null
return
result
return
result
}
}
...
@@ -54,7 +41,10 @@ module.exports = (function() {
...
@@ -54,7 +41,10 @@ module.exports = (function() {
,
self
=
this
,
self
=
this
this
.
attributes
.
concat
(
this
.
__eagerlyLoadedAssociations
).
forEach
(
function
(
attr
)
{
this
.
attributes
.
concat
(
this
.
__eagerlyLoadedAssociations
).
forEach
(
function
(
attr
)
{
result
[
attr
]
=
self
[
attr
]
result
[
attr
]
=
self
.
dataValues
.
hasOwnProperty
(
attr
)
?
self
.
dataValues
[
attr
]
:
self
[
attr
]
;
})
})
return
result
return
result
...
@@ -67,7 +57,7 @@ module.exports = (function() {
...
@@ -67,7 +57,7 @@ module.exports = (function() {
,
self
=
this
,
self
=
this
Utils
.
_
.
each
(
this
.
__factory
.
primaryKeys
,
function
(
_
,
attr
)
{
Utils
.
_
.
each
(
this
.
__factory
.
primaryKeys
,
function
(
_
,
attr
)
{
result
[
attr
]
=
self
[
attr
]
result
[
attr
]
=
self
.
dataValues
[
attr
]
})
})
return
result
return
result
...
@@ -85,13 +75,21 @@ module.exports = (function() {
...
@@ -85,13 +75,21 @@ module.exports = (function() {
}
}
primaryKeys
.
forEach
(
function
(
identifier
)
{
primaryKeys
.
forEach
(
function
(
identifier
)
{
result
[
identifier
]
=
self
[
identifier
]
result
[
identifier
]
=
self
.
dataValues
[
identifier
]
})
})
return
result
return
result
}
}
})
})
DAO
.
prototype
.
getDataValue
=
function
(
name
)
{
return
this
.
dataValues
&&
this
.
dataValues
.
hasOwnProperty
(
name
)
?
this
.
dataValues
[
name
]
:
this
[
name
]
}
DAO
.
prototype
.
setDataValue
=
function
(
name
,
value
)
{
this
.
dataValues
[
name
]
=
value
}
// if an array with field names is passed to save()
// if an array with field names is passed to save()
// only those fields will be updated
// only those fields will be updated
DAO
.
prototype
.
save
=
function
(
fields
)
{
DAO
.
prototype
.
save
=
function
(
fields
)
{
...
@@ -111,9 +109,11 @@ module.exports = (function() {
...
@@ -111,9 +109,11 @@ module.exports = (function() {
}
}
}
}
var
tmpVals
=
self
.
values
fields
.
forEach
(
function
(
field
)
{
fields
.
forEach
(
function
(
field
)
{
if
(
self
.
value
s
[
field
]
!==
undefined
)
{
if
(
tmpVal
s
[
field
]
!==
undefined
)
{
values
[
field
]
=
self
.
value
s
[
field
]
values
[
field
]
=
tmpVal
s
[
field
]
}
}
})
})
}
}
...
@@ -146,8 +146,8 @@ module.exports = (function() {
...
@@ -146,8 +146,8 @@ module.exports = (function() {
}
}
}
}
if
(
this
.
__options
.
timestamps
&&
this
.
hasOwnProperty
(
updatedAtAttr
))
{
if
(
this
.
__options
.
timestamps
&&
this
.
dataValues
.
hasOwnProperty
(
updatedAtAttr
))
{
this
[
updatedAtAttr
]
=
values
[
updatedAtAttr
]
=
Utils
.
now
()
this
.
dataValues
[
updatedAtAttr
]
=
values
[
updatedAtAttr
]
=
Utils
.
now
()
}
}
var
errors
=
this
.
validate
()
var
errors
=
this
.
validate
()
...
@@ -301,7 +301,7 @@ module.exports = (function() {
...
@@ -301,7 +301,7 @@ module.exports = (function() {
DAO
.
prototype
.
destroy
=
function
()
{
DAO
.
prototype
.
destroy
=
function
()
{
if
(
this
.
__options
.
timestamps
&&
this
.
__options
.
paranoid
)
{
if
(
this
.
__options
.
timestamps
&&
this
.
__options
.
paranoid
)
{
var
attr
=
this
.
__options
.
underscored
?
'deleted_at'
:
'deletedAt'
var
attr
=
this
.
__options
.
underscored
?
'deleted_at'
:
'deletedAt'
this
[
attr
]
=
new
Date
()
this
.
dataValues
[
attr
]
=
new
Date
()
return
this
.
save
()
return
this
.
save
()
}
else
{
}
else
{
var
identifier
=
this
.
__options
.
hasPrimaryKeys
?
this
.
primaryKeyValues
:
this
.
id
var
identifier
=
this
.
__options
.
hasPrimaryKeys
?
this
.
primaryKeyValues
:
this
.
id
...
@@ -362,7 +362,37 @@ module.exports = (function() {
...
@@ -362,7 +362,37 @@ module.exports = (function() {
}
}
DAO
.
prototype
.
addAttribute
=
function
(
attribute
,
value
)
{
DAO
.
prototype
.
addAttribute
=
function
(
attribute
,
value
)
{
this
[
attribute
]
=
value
if
(
typeof
this
.
dataValues
[
attribute
]
!==
'undefined'
)
return
;
if
(
this
.
booleanValues
.
length
&&
this
.
booleanValues
.
indexOf
(
attribute
)
!==
-
1
)
// transform integer 0,1 into boolean
value
=
!!
value
;
var
has
=
(
function
(
o
)
{
var
predef
=
Object
.
getOwnPropertyDescriptor
(
o
,
attribute
);
if
(
predef
&&
predef
.
hasOwnProperty
(
'value'
))
return
true
;
// true here means 'this property exist as a simple value property, do not place setters or getters at all'
return
{
get
:
(
predef
&&
predef
.
hasOwnProperty
(
'get'
)
?
predef
.
get
:
null
)
||
o
.
__lookupGetter__
(
attribute
),
set
:
(
predef
&&
predef
.
hasOwnProperty
(
'set'
)
?
predef
.
set
:
null
)
||
o
.
__lookupSetter__
(
attribute
)
};
})(
this
);
// @ node-v0.8.19:
// calling __defineGetter__ destroys any previously defined setters for the attribute in
// question *if* that property setter was defined on the object's prototype (which is what
// we do in dao-factory) ... therefore we need to [re]define both the setter and getter
// here with either the function that already existed OR the default/automatic definition
//
// (the same is true for __defineSetter and 'prototype' getters)
if
(
has
!==
true
)
{
this
.
__defineGetter__
(
attribute
,
has
.
get
||
function
()
{
return
this
.
dataValues
[
attribute
];
});
this
.
__defineSetter__
(
attribute
,
has
.
set
||
function
(
v
)
{
this
.
dataValues
[
attribute
]
=
v
;
});
}
this
[
attribute
]
=
value
;
}
}
DAO
.
prototype
.
setValidators
=
function
(
attribute
,
validators
)
{
DAO
.
prototype
.
setValidators
=
function
(
attribute
,
validators
)
{
...
@@ -376,8 +406,13 @@ module.exports = (function() {
...
@@ -376,8 +406,13 @@ module.exports = (function() {
// private
// private
var
initAttributes
=
function
(
values
,
isNewRecord
)
{
var
initAttributes
=
function
(
values
,
isNewRecord
)
{
// set id to null if not passed as value, a newly created dao has no id
var
defaults
=
this
.
hasPrimaryKeys
?
{}
:
{
id
:
null
},
attrs
=
{},
key
;
// add all passed values to the dao and store the attribute names in this.attributes
// add all passed values to the dao and store the attribute names in this.attributes
for
(
var
key
in
values
)
{
for
(
key
in
values
)
{
if
(
values
.
hasOwnProperty
(
key
))
{
if
(
values
.
hasOwnProperty
(
key
))
{
if
(
typeof
values
[
key
]
===
"string"
&&
!!
this
.
__factory
&&
!!
this
.
__factory
.
rawAttributes
[
key
]
&&
!!
this
.
__factory
.
rawAttributes
[
key
].
type
&&
!!
this
.
__factory
.
rawAttributes
[
key
].
type
.
type
&&
this
.
__factory
.
rawAttributes
[
key
].
type
.
type
===
DataTypes
.
HSTORE
.
type
)
{
if
(
typeof
values
[
key
]
===
"string"
&&
!!
this
.
__factory
&&
!!
this
.
__factory
.
rawAttributes
[
key
]
&&
!!
this
.
__factory
.
rawAttributes
[
key
].
type
&&
!!
this
.
__factory
.
rawAttributes
[
key
].
type
.
type
&&
this
.
__factory
.
rawAttributes
[
key
].
type
.
type
===
DataTypes
.
HSTORE
.
type
)
{
values
[
key
]
=
this
.
QueryInterface
.
QueryGenerator
.
toHstore
(
values
[
key
])
values
[
key
]
=
this
.
QueryInterface
.
QueryGenerator
.
toHstore
(
values
[
key
])
...
@@ -387,10 +422,6 @@ module.exports = (function() {
...
@@ -387,10 +422,6 @@ module.exports = (function() {
}
}
}
}
// set id to null if not passed as value
// a newly created dao has no id
var
defaults
=
this
.
hasPrimaryKeys
?
{}
:
{
id
:
null
}
if
(
this
.
__options
.
timestamps
&&
isNewRecord
)
{
if
(
this
.
__options
.
timestamps
&&
isNewRecord
)
{
defaults
[
this
.
__options
.
underscored
?
'created_at'
:
'createdAt'
]
=
Utils
.
now
()
defaults
[
this
.
__options
.
underscored
?
'created_at'
:
'createdAt'
]
=
Utils
.
now
()
defaults
[
this
.
__options
.
underscored
?
'updated_at'
:
'updatedAt'
]
=
Utils
.
now
()
defaults
[
this
.
__options
.
underscored
?
'updated_at'
:
'updatedAt'
]
=
Utils
.
now
()
...
@@ -398,17 +429,38 @@ module.exports = (function() {
...
@@ -398,17 +429,38 @@ module.exports = (function() {
if
(
this
.
__options
.
paranoid
)
{
if
(
this
.
__options
.
paranoid
)
{
defaults
[
this
.
__options
.
underscored
?
'deleted_at'
:
'deletedAt'
]
=
null
defaults
[
this
.
__options
.
underscored
?
'deleted_at'
:
'deletedAt'
]
=
null
}
}
if
(
this
.
hasDefaultValues
)
{
Utils
.
_
.
each
(
this
.
defaultValues
,
function
(
valueFn
,
key
)
{
if
(
!
defaults
.
hasOwnProperty
(
key
))
defaults
[
key
]
=
valueFn
()
})
}
}
}
if
(
Utils
.
_
.
size
(
defaults
))
{
if
(
Utils
.
_
.
size
(
defaults
))
{
for
(
var
attr
in
defaults
)
{
for
(
key
in
defaults
)
{
var
value
=
defaults
[
attr
]
attrs
[
key
]
=
Utils
.
toDefaultValue
(
defaults
[
key
])
}
}
Utils
.
_
.
each
(
this
.
attributes
,
function
(
key
)
{
if
(
!
attrs
.
hasOwnProperty
(
key
))
{
attrs
[
key
]
=
undefined
}
})
if
(
!
this
.
hasOwnProperty
(
attr
))
{
if
(
values
)
{
this
.
addAttribute
(
attr
,
Utils
.
toDefaultValue
(
value
))
for
(
key
in
values
)
{
if
(
values
.
hasOwnProperty
(
key
))
{
attrs
[
key
]
=
values
[
key
]
}
}
}
}
}
}
for
(
key
in
attrs
)
{
this
.
addAttribute
(
key
,
attrs
[
key
])
}
}
}
return
DAO
return
DAO
...
...
spec/dao-factory.spec.js
View file @
ec4f8ef
...
@@ -100,6 +100,82 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
...
@@ -100,6 +100,82 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
var
user
=
this
.
User
.
build
({
username
:
'John Wayne'
})
var
user
=
this
.
User
.
build
({
username
:
'John Wayne'
})
expect
(
user
.
selectedValues
).
toEqual
({
username
:
'John Wayne'
})
expect
(
user
.
selectedValues
).
toEqual
({
username
:
'John Wayne'
})
})
})
it
(
"attaches getter and setter methods from attribute definition"
,
function
()
{
var
Product
=
this
.
sequelize
.
define
(
'ProductWithSettersAndGetters1'
,
{
price
:
{
type
:
Sequelize
.
INTEGER
,
get
:
function
()
{
return
'answer = '
+
this
.
getDataValue
(
'price'
);
},
set
:
function
(
v
)
{
return
this
.
setDataValue
(
'price'
,
v
+
42
);
}
}
},{
});
expect
(
Product
.
build
({
price
:
42
}).
price
).
toEqual
(
'answer = 84'
);
var
p
=
Product
.
build
({
price
:
1
});
expect
(
p
.
price
).
toEqual
(
'answer = 43'
);
p
.
price
=
0
;
expect
(
p
.
price
).
toEqual
(
'answer = 42'
);
// ah finally the right answer :-)
})
it
(
"attaches getter and setter methods from options"
,
function
()
{
var
Product
=
this
.
sequelize
.
define
(
'ProductWithSettersAndGetters2'
,
{
priceInCents
:
{
type
:
Sequelize
.
INTEGER
}
},{
setterMethods
:
{
price
:
function
(
value
)
{
this
.
dataValues
.
priceInCents
=
value
*
100
;
}
},
getterMethods
:
{
price
:
function
()
{
return
'$'
+
(
this
.
getDataValue
(
'priceInCents'
)
/
100
);
},
priceInCents
:
function
()
{
return
this
.
dataValues
.
priceInCents
;
}
}
});
expect
(
Product
.
build
({
price
:
20
}).
priceInCents
).
toEqual
(
20
*
100
);
expect
(
Product
.
build
({
priceInCents
:
30
*
100
}).
price
).
toEqual
(
'$'
+
30
);
})
it
(
"attaches getter and setter methods from options only if not defined in attribute"
,
function
()
{
var
Product
=
this
.
sequelize
.
define
(
'ProductWithSettersAndGetters3'
,
{
price1
:
{
type
:
Sequelize
.
INTEGER
,
set
:
function
(
v
)
{
this
.
setDataValue
(
'price1'
,
v
*
10
);
}
},
price2
:
{
type
:
Sequelize
.
INTEGER
,
get
:
function
(
v
)
{
return
this
.
getDataValue
(
'price2'
)
*
10
;
}
}
},{
setterMethods
:
{
price1
:
function
(
v
)
{
this
.
setDataValue
(
'price1'
,
v
*
100
);
}
},
getterMethods
:
{
price2
:
function
()
{
return
'$'
+
this
.
getDataValue
(
'price2'
);
}
}
});
var
p
=
Product
.
build
({
price1
:
1
,
price2
:
2
});
expect
(
p
.
price1
).
toEqual
(
10
);
expect
(
p
.
price2
).
toEqual
(
20
);
})
})
})
describe
(
'findOrCreate'
,
function
()
{
describe
(
'findOrCreate'
,
function
()
{
...
...
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