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 e3c32c94
authored
Aug 02, 2013
by
Sascha Depold
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'mstorgaard-dirty-tracking'
2 parents
e83132dd
5b0d6497
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
178 additions
and
6 deletions
lib/dao-factory.js
lib/dao.js
lib/dialects/abstract/query.js
lib/utils.js
test/dao.test.js
lib/dao-factory.js
View file @
e3c32c9
...
@@ -382,7 +382,7 @@ module.exports = (function() {
...
@@ -382,7 +382,7 @@ module.exports = (function() {
}
}
DAOFactory
.
prototype
.
build
=
function
(
values
,
options
)
{
DAOFactory
.
prototype
.
build
=
function
(
values
,
options
)
{
options
=
options
||
{
isNewRecord
:
true
}
options
=
options
||
{
isNewRecord
:
true
,
isDirty
:
true
}
var
self
=
this
var
self
=
this
,
instance
=
new
this
.
DAO
(
values
,
this
.
options
,
options
.
isNewRecord
)
,
instance
=
new
this
.
DAO
(
values
,
this
.
options
,
options
.
isNewRecord
)
...
@@ -390,6 +390,7 @@ module.exports = (function() {
...
@@ -390,6 +390,7 @@ module.exports = (function() {
instance
.
isNewRecord
=
options
.
isNewRecord
instance
.
isNewRecord
=
options
.
isNewRecord
instance
.
daoFactoryName
=
this
.
name
instance
.
daoFactoryName
=
this
.
name
instance
.
daoFactory
=
this
instance
.
daoFactory
=
this
instance
.
isDirty
=
options
.
isDirty
return
instance
return
instance
}
}
...
...
lib/dao.js
View file @
e3c32c9
...
@@ -84,10 +84,15 @@ module.exports = (function() {
...
@@ -84,10 +84,15 @@ module.exports = (function() {
DAO
.
prototype
.
getDataValue
=
function
(
name
)
{
DAO
.
prototype
.
getDataValue
=
function
(
name
)
{
return
this
.
dataValues
&&
this
.
dataValues
.
hasOwnProperty
(
name
)
?
this
.
dataValues
[
name
]
:
this
[
name
]
return
this
.
dataValues
&&
this
.
dataValues
.
hasOwnProperty
(
name
)
?
this
.
dataValues
[
name
]
:
this
[
name
]
}
}
DAO
.
prototype
.
get
=
DAO
.
prototype
.
getDataValue
DAO
.
prototype
.
setDataValue
=
function
(
name
,
value
)
{
DAO
.
prototype
.
setDataValue
=
function
(
name
,
value
)
{
if
(
Utils
.
hasChanged
(
this
.
dataValues
[
name
],
value
))
{
this
.
isDirty
=
true
}
this
.
dataValues
[
name
]
=
value
this
.
dataValues
[
name
]
=
value
}
}
DAO
.
prototype
.
set
=
DAO
.
prototype
.
setDataValue
// 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
...
@@ -149,6 +154,7 @@ module.exports = (function() {
...
@@ -149,6 +154,7 @@ module.exports = (function() {
}).
run
()
}).
run
()
}
}
else
if
(
this
.
isNewRecord
)
{
else
if
(
this
.
isNewRecord
)
{
this
.
isDirty
=
false
return
this
.
QueryInterface
.
insert
(
this
,
this
.
QueryInterface
.
QueryGenerator
.
addSchema
(
this
.
__factory
),
values
)
return
this
.
QueryInterface
.
insert
(
this
,
this
.
QueryInterface
.
QueryGenerator
.
addSchema
(
this
.
__factory
),
values
)
}
else
{
}
else
{
var
identifier
=
this
.
__options
.
hasPrimaryKeys
?
this
.
primaryKeyValues
:
{
id
:
this
.
id
};
var
identifier
=
this
.
__options
.
hasPrimaryKeys
?
this
.
primaryKeyValues
:
{
id
:
this
.
id
};
...
@@ -157,6 +163,7 @@ module.exports = (function() {
...
@@ -157,6 +163,7 @@ module.exports = (function() {
identifier
=
this
.
__options
.
whereCollection
;
identifier
=
this
.
__options
.
whereCollection
;
}
}
this
.
isDirty
=
false
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
)
...
@@ -191,6 +198,7 @@ module.exports = (function() {
...
@@ -191,6 +198,7 @@ module.exports = (function() {
this
[
valueName
]
=
obj
.
values
[
valueName
]
this
[
valueName
]
=
obj
.
values
[
valueName
]
}
}
}
}
this
.
isDirty
=
false
emitter
.
emit
(
'success'
,
this
)
emitter
.
emit
(
'success'
,
this
)
}.
bind
(
this
))
}.
bind
(
this
))
}.
bind
(
this
)).
run
()
}.
bind
(
this
)).
run
()
...
@@ -224,14 +232,21 @@ module.exports = (function() {
...
@@ -224,14 +232,21 @@ module.exports = (function() {
readOnlyAttributes
.
push
(
'updatedAt'
)
readOnlyAttributes
.
push
(
'updatedAt'
)
readOnlyAttributes
.
push
(
'deletedAt'
)
readOnlyAttributes
.
push
(
'deletedAt'
)
var
isDirty
=
this
.
isDirty
Utils
.
_
.
each
(
updates
,
function
(
value
,
attr
)
{
Utils
.
_
.
each
(
updates
,
function
(
value
,
attr
)
{
var
updateAllowed
=
(
var
updateAllowed
=
(
(
readOnlyAttributes
.
indexOf
(
attr
)
==
-
1
)
&&
(
readOnlyAttributes
.
indexOf
(
attr
)
==
-
1
)
&&
(
readOnlyAttributes
.
indexOf
(
Utils
.
_
.
underscored
(
attr
))
==
-
1
)
&&
(
readOnlyAttributes
.
indexOf
(
Utils
.
_
.
underscored
(
attr
))
==
-
1
)
&&
(
self
.
attributes
.
indexOf
(
attr
)
>
-
1
)
(
self
.
attributes
.
indexOf
(
attr
)
>
-
1
)
)
)
updateAllowed
&&
(
self
[
attr
]
=
value
)
if
(
updateAllowed
)
{
if
(
Utils
.
hasChanged
(
self
[
attr
],
value
))
{
isDirty
=
true
}
self
[
attr
]
=
value
}
})
})
this
.
isDirty
=
isDirty
}
}
DAO
.
prototype
.
destroy
=
function
()
{
DAO
.
prototype
.
destroy
=
function
()
{
...
@@ -330,7 +345,19 @@ module.exports = (function() {
...
@@ -330,7 +345,19 @@ module.exports = (function() {
// (the same is true for __defineSetter and 'prototype' getters)
// (the same is true for __defineSetter and 'prototype' getters)
if
(
has
!==
true
)
{
if
(
has
!==
true
)
{
this
.
__defineGetter__
(
attribute
,
has
.
get
||
function
()
{
return
this
.
dataValues
[
attribute
];
});
this
.
__defineGetter__
(
attribute
,
has
.
get
||
function
()
{
return
this
.
dataValues
[
attribute
];
});
this
.
__defineSetter__
(
attribute
,
has
.
set
||
function
(
v
)
{
this
.
dataValues
[
attribute
]
=
v
;
});
this
.
__defineSetter__
(
attribute
,
has
.
set
||
function
(
v
)
{
if
(
Utils
.
hasChanged
(
this
.
dataValues
[
attribute
],
v
))
{
//Only dirty the object if the change is not due to id, touchedAt, createdAt or updatedAt being initiated
var
updatedAtAttr
=
this
.
__options
.
underscored
?
'updated_at'
:
'updatedAt'
,
createdAtAttr
=
this
.
__options
.
underscored
?
'created_at'
:
'createdAt'
,
touchedAtAttr
=
this
.
__options
.
underscored
?
'touched_at'
:
'touchedAt'
if
(
this
.
dataValues
[
attribute
]
||
(
attribute
!=
'id'
&&
attribute
!=
touchedAtAttr
&&
attribute
!=
createdAtAttr
&&
attribute
!=
updatedAtAttr
))
{
this
.
isDirty
=
true
}
}
this
.
dataValues
[
attribute
]
=
v
});
}
}
this
[
attribute
]
=
value
;
this
[
attribute
]
=
value
;
...
...
lib/dialects/abstract/query.js
View file @
e3c32c9
...
@@ -262,7 +262,7 @@ module.exports = (function() {
...
@@ -262,7 +262,7 @@ module.exports = (function() {
result
=
transformRowsWithEagerLoadingIntoDaos
.
call
(
this
,
results
)
result
=
transformRowsWithEagerLoadingIntoDaos
.
call
(
this
,
results
)
}
else
{
}
else
{
result
=
results
.
map
(
function
(
result
)
{
result
=
results
.
map
(
function
(
result
)
{
return
this
.
callee
.
build
(
result
,
{
isNewRecord
:
false
})
return
this
.
callee
.
build
(
result
,
{
isNewRecord
:
false
,
isDirty
:
false
})
}.
bind
(
this
))
}.
bind
(
this
))
}
}
...
@@ -287,7 +287,7 @@ module.exports = (function() {
...
@@ -287,7 +287,7 @@ module.exports = (function() {
var
transformRowWithEagerLoadingIntoDao
=
function
(
result
,
dao
)
{
var
transformRowWithEagerLoadingIntoDao
=
function
(
result
,
dao
)
{
// let's build the actual dao instance first...
// let's build the actual dao instance first...
dao
=
dao
||
this
.
callee
.
build
(
result
[
this
.
callee
.
tableName
],
{
isNewRecord
:
false
})
dao
=
dao
||
this
.
callee
.
build
(
result
[
this
.
callee
.
tableName
],
{
isNewRecord
:
false
,
isDirty
:
false
})
// ... and afterwards the prefetched associations
// ... and afterwards the prefetched associations
for
(
var
tableName
in
result
)
{
for
(
var
tableName
in
result
)
{
...
@@ -323,7 +323,7 @@ module.exports = (function() {
...
@@ -323,7 +323,7 @@ module.exports = (function() {
accessor
=
accessor
.
slice
(
0
,
1
).
toLowerCase
()
+
accessor
.
slice
(
1
)
accessor
=
accessor
.
slice
(
0
,
1
).
toLowerCase
()
+
accessor
.
slice
(
1
)
associationData
.
forEach
(
function
(
data
)
{
associationData
.
forEach
(
function
(
data
)
{
var
daoInstance
=
associatedDaoFactory
.
build
(
data
,
{
isNewRecord
:
false
})
var
daoInstance
=
associatedDaoFactory
.
build
(
data
,
{
isNewRecord
:
false
,
isDirty
:
false
})
,
isEmpty
=
!
Utils
.
firstValueOfHash
(
daoInstance
.
identifiers
)
,
isEmpty
=
!
Utils
.
firstValueOfHash
(
daoInstance
.
identifiers
)
if
([
'BelongsTo'
,
'HasOne'
].
indexOf
(
association
.
associationType
)
>
-
1
)
{
if
([
'BelongsTo'
,
'HasOne'
].
indexOf
(
association
.
associationType
)
>
-
1
)
{
...
...
lib/utils.js
View file @
e3c32c9
...
@@ -252,6 +252,23 @@ var Utils = module.exports = {
...
@@ -252,6 +252,23 @@ var Utils = module.exports = {
isHash
:
function
(
obj
)
{
isHash
:
function
(
obj
)
{
return
Utils
.
_
.
isObject
(
obj
)
&&
!
Array
.
isArray
(
obj
);
return
Utils
.
_
.
isObject
(
obj
)
&&
!
Array
.
isArray
(
obj
);
},
},
hasChanged
:
function
(
attrValue
,
value
)
{
//If attribute value is Date, check value as a date
if
(
Utils
.
_
.
isDate
(
attrValue
)
&&
!
Utils
.
_
.
isDate
(
value
))
{
value
=
new
Date
(
value
)
}
if
(
Utils
.
_
.
isDate
(
attrValue
))
{
return
attrValue
.
valueOf
()
!==
value
.
valueOf
()
}
//If both of them are empty, don't set as changed
if
((
attrValue
===
undefined
||
attrValue
===
null
||
attrValue
===
''
)
&&
(
value
===
undefined
||
value
===
null
||
value
===
''
))
{
return
false
}
return
attrValue
!==
value
},
argsArePrimaryKeys
:
function
(
args
,
primaryKeys
)
{
argsArePrimaryKeys
:
function
(
args
,
primaryKeys
)
{
var
result
=
(
args
.
length
==
Object
.
keys
(
primaryKeys
).
length
)
var
result
=
(
args
.
length
==
Object
.
keys
(
primaryKeys
).
length
)
if
(
result
)
{
if
(
result
)
{
...
...
test/dao.test.js
View file @
e3c32c9
...
@@ -19,6 +19,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
...
@@ -19,6 +19,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
touchedAt
:
{
type
:
DataTypes
.
DATE
,
defaultValue
:
DataTypes
.
NOW
},
touchedAt
:
{
type
:
DataTypes
.
DATE
,
defaultValue
:
DataTypes
.
NOW
},
aNumber
:
{
type
:
DataTypes
.
INTEGER
},
aNumber
:
{
type
:
DataTypes
.
INTEGER
},
bNumber
:
{
type
:
DataTypes
.
INTEGER
},
bNumber
:
{
type
:
DataTypes
.
INTEGER
},
aDate
:
{
type
:
DataTypes
.
DATE
},
validateTest
:
{
validateTest
:
{
type
:
DataTypes
.
INTEGER
,
type
:
DataTypes
.
INTEGER
,
...
@@ -110,6 +111,132 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
...
@@ -110,6 +111,132 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
})
})
})
})
describe
(
'isDirty'
,
function
()
{
it
(
'returns true for non-saved objects'
,
function
(
done
)
{
var
user
=
this
.
User
.
build
({
username
:
'user'
})
expect
(
user
.
id
).
to
.
be
.
null
expect
(
user
.
isDirty
).
to
.
be
.
true
done
()
})
it
(
"returns false for saved objects"
,
function
(
done
)
{
this
.
User
.
build
({
username
:
'user'
}).
save
().
success
(
function
(
user
)
{
expect
(
user
.
isDirty
).
to
.
be
.
false
done
()
})
})
it
(
"returns true for changed attribute"
,
function
(
done
)
{
this
.
User
.
create
({
username
:
'user'
}).
success
(
function
(
user
)
{
user
.
username
=
'new'
expect
(
user
.
isDirty
).
to
.
be
.
true
done
()
})
})
it
(
"returns false for non-changed attribute"
,
function
(
done
)
{
this
.
User
.
create
({
username
:
'user'
}).
success
(
function
(
user
)
{
user
.
username
=
'user'
expect
(
user
.
isDirty
).
to
.
be
.
false
done
()
})
})
it
(
"returns false for non-changed date attribute"
,
function
(
done
)
{
this
.
User
.
create
({
aDate
:
new
Date
(
2013
,
6
,
31
,
14
,
25
,
21
)
}).
success
(
function
(
user
)
{
user
.
aDate
=
'2013-07-31 14:25:21'
expect
(
user
.
isDirty
).
to
.
be
.
false
done
()
})
})
it
(
"returns false for two empty attributes"
,
function
(
done
)
{
this
.
User
.
create
({
username
:
null
}).
success
(
function
(
user
)
{
user
.
username
=
''
expect
(
user
.
isDirty
).
to
.
be
.
false
done
()
})
})
it
(
"returns true for bulk changed attribute"
,
function
(
done
)
{
this
.
User
.
create
({
username
:
'user'
}).
success
(
function
(
user
)
{
user
.
setAttributes
({
username
:
'new'
,
aNumber
:
1
})
expect
(
user
.
isDirty
).
to
.
be
.
true
done
()
})
})
it
(
"returns false for bulk non-changed attribute"
,
function
(
done
)
{
this
.
User
.
create
({
username
:
'user'
}).
success
(
function
(
user
)
{
user
.
setAttributes
({
username
:
'user'
})
expect
(
user
.
isDirty
).
to
.
be
.
false
done
()
})
})
it
(
"returns true for changed and bulk non-changed attribute"
,
function
(
done
)
{
this
.
User
.
create
({
username
:
'user'
}).
success
(
function
(
user
)
{
user
.
aNumber
=
23
user
.
setAttributes
({
username
:
'user'
})
expect
(
user
.
isDirty
).
to
.
be
.
true
done
()
})
})
it
(
"returns true for changed attribute and false for saved object"
,
function
(
done
)
{
this
.
User
.
create
({
username
:
'user'
}).
success
(
function
(
user
)
{
user
.
username
=
'new'
expect
(
user
.
isDirty
).
to
.
be
.
true
user
.
save
().
success
(
function
()
{
expect
(
user
.
isDirty
).
to
.
be
.
false
done
()
})
})
})
it
(
"returns false for created objects"
,
function
(
done
)
{
this
.
User
.
create
({
username
:
'user'
}).
success
(
function
(
user
)
{
expect
(
user
.
isDirty
).
to
.
be
.
false
done
()
})
})
it
(
"returns false for objects found by find method"
,
function
(
done
)
{
var
self
=
this
this
.
User
.
create
({
username
:
'user'
}).
success
(
function
(
user
)
{
self
.
User
.
find
(
user
.
id
).
success
(
function
(
user
)
{
expect
(
user
.
isDirty
).
to
.
be
.
false
done
()
})
})
})
it
(
"returns false for objects found by findAll method"
,
function
(
done
)
{
var
self
=
this
,
users
=
[]
for
(
var
i
=
0
;
i
<
10
;
i
++
)
{
users
[
users
.
length
]
=
{
username
:
'user'
}
}
this
.
User
.
bulkCreate
(
users
).
success
(
function
()
{
self
.
User
.
findAll
().
success
(
function
(
users
)
{
users
.
forEach
(
function
(
u
)
{
expect
(
u
.
isDirty
).
to
.
be
.
false
})
done
()
})
})
})
})
describe
(
'increment'
,
function
()
{
describe
(
'increment'
,
function
()
{
beforeEach
(
function
(
done
)
{
beforeEach
(
function
(
done
)
{
this
.
User
.
create
({
id
:
1
,
aNumber
:
0
,
bNumber
:
0
}).
complete
(
function
(){
this
.
User
.
create
({
id
:
1
,
aNumber
:
0
,
bNumber
:
0
}).
complete
(
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