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 03137ae8
authored
Aug 02, 2013
by
Sascha Depold
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dirty-tracking' of
https://github.com/mstorgaard/sequelize
into ms…
…torgaard-dirty-tracking
2 parents
e83132dd
a9524acf
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
175 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 @
03137ae
...
...
@@ -382,7 +382,7 @@ module.exports = (function() {
}
DAOFactory
.
prototype
.
build
=
function
(
values
,
options
)
{
options
=
options
||
{
isNewRecord
:
true
}
options
=
options
||
{
isNewRecord
:
true
,
isDirty
:
true
}
var
self
=
this
,
instance
=
new
this
.
DAO
(
values
,
this
.
options
,
options
.
isNewRecord
)
...
...
@@ -390,6 +390,7 @@ module.exports = (function() {
instance
.
isNewRecord
=
options
.
isNewRecord
instance
.
daoFactoryName
=
this
.
name
instance
.
daoFactory
=
this
instance
.
isDirty
=
options
.
isDirty
return
instance
}
...
...
lib/dao.js
View file @
03137ae
...
...
@@ -84,10 +84,15 @@ module.exports = (function() {
DAO
.
prototype
.
getDataValue
=
function
(
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
)
{
if
(
Utils
.
didChange
(
this
.
dataValues
[
name
],
value
))
{
this
.
isDirty
=
true
}
this
.
dataValues
[
name
]
=
value
}
DAO
.
prototype
.
set
=
DAO
.
prototype
.
setDataValue
// if an array with field names is passed to save()
// only those fields will be updated
...
...
@@ -149,6 +154,7 @@ module.exports = (function() {
}).
run
()
}
else
if
(
this
.
isNewRecord
)
{
this
.
isDirty
=
false
return
this
.
QueryInterface
.
insert
(
this
,
this
.
QueryInterface
.
QueryGenerator
.
addSchema
(
this
.
__factory
),
values
)
}
else
{
var
identifier
=
this
.
__options
.
hasPrimaryKeys
?
this
.
primaryKeyValues
:
{
id
:
this
.
id
};
...
...
@@ -157,6 +163,7 @@ module.exports = (function() {
identifier
=
this
.
__options
.
whereCollection
;
}
this
.
isDirty
=
false
var
tableName
=
this
.
QueryInterface
.
QueryGenerator
.
addSchema
(
this
.
__factory
)
,
query
=
this
.
QueryInterface
.
update
(
this
,
tableName
,
values
,
identifier
)
...
...
@@ -191,6 +198,7 @@ module.exports = (function() {
this
[
valueName
]
=
obj
.
values
[
valueName
]
}
}
this
.
isDirty
=
false
emitter
.
emit
(
'success'
,
this
)
}.
bind
(
this
))
}.
bind
(
this
)).
run
()
...
...
@@ -224,14 +232,21 @@ module.exports = (function() {
readOnlyAttributes
.
push
(
'updatedAt'
)
readOnlyAttributes
.
push
(
'deletedAt'
)
var
isDirty
=
this
.
isDirty
Utils
.
_
.
each
(
updates
,
function
(
value
,
attr
)
{
var
updateAllowed
=
(
(
readOnlyAttributes
.
indexOf
(
attr
)
==
-
1
)
&&
(
readOnlyAttributes
.
indexOf
(
Utils
.
_
.
underscored
(
attr
))
==
-
1
)
&&
(
self
.
attributes
.
indexOf
(
attr
)
>
-
1
)
)
updateAllowed
&&
(
self
[
attr
]
=
value
)
if
(
updateAllowed
)
{
if
(
Utils
.
didChange
(
self
[
attr
],
value
))
{
isDirty
=
true
}
self
[
attr
]
=
value
}
})
this
.
isDirty
=
isDirty
}
DAO
.
prototype
.
destroy
=
function
()
{
...
...
@@ -330,7 +345,19 @@ module.exports = (function() {
// (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
.
__defineSetter__
(
attribute
,
has
.
set
||
function
(
v
)
{
if
(
Utils
.
didChange
(
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
;
...
...
lib/dialects/abstract/query.js
View file @
03137ae
...
...
@@ -262,7 +262,7 @@ module.exports = (function() {
result
=
transformRowsWithEagerLoadingIntoDaos
.
call
(
this
,
results
)
}
else
{
result
=
results
.
map
(
function
(
result
)
{
return
this
.
callee
.
build
(
result
,
{
isNewRecord
:
false
})
return
this
.
callee
.
build
(
result
,
{
isNewRecord
:
false
,
isDirty
:
false
})
}.
bind
(
this
))
}
...
...
@@ -287,7 +287,7 @@ module.exports = (function() {
var
transformRowWithEagerLoadingIntoDao
=
function
(
result
,
dao
)
{
// 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
for
(
var
tableName
in
result
)
{
...
...
@@ -323,7 +323,7 @@ module.exports = (function() {
accessor
=
accessor
.
slice
(
0
,
1
).
toLowerCase
()
+
accessor
.
slice
(
1
)
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
)
if
([
'BelongsTo'
,
'HasOne'
].
indexOf
(
association
.
associationType
)
>
-
1
)
{
...
...
lib/utils.js
View file @
03137ae
...
...
@@ -252,6 +252,20 @@ var Utils = module.exports = {
isHash
:
function
(
obj
)
{
return
Utils
.
_
.
isObject
(
obj
)
&&
!
Array
.
isArray
(
obj
);
},
didChange
:
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
)
{
var
result
=
(
args
.
length
==
Object
.
keys
(
primaryKeys
).
length
)
if
(
result
)
{
...
...
test/dao.test.js
View file @
03137ae
...
...
@@ -19,6 +19,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
touchedAt
:
{
type
:
DataTypes
.
DATE
,
defaultValue
:
DataTypes
.
NOW
},
aNumber
:
{
type
:
DataTypes
.
INTEGER
},
bNumber
:
{
type
:
DataTypes
.
INTEGER
},
aDate
:
{
type
:
DataTypes
.
DATE
},
validateTest
:
{
type
:
DataTypes
.
INTEGER
,
...
...
@@ -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
()
{
beforeEach
(
function
(
done
)
{
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