Skip to content

Commit 9558242

Browse files
fix(paranoid): use Utils.now to query for paranoid records (#8485)
1 parent bf5fa6d commit 9558242

File tree

4 files changed

+62
-50
lines changed

4 files changed

+62
-50
lines changed

lib/model.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,16 @@ class Model {
7777
const deletedAtCol = model._timestampAttributes.deletedAt;
7878
const deletedAtAttribute = model.rawAttributes[deletedAtCol];
7979
const deletedAtObject = {};
80+
const now = Utils.now(this.sequelize.options.dialect);
81+
8082
let deletedAtDefaultValue = deletedAtAttribute.hasOwnProperty('defaultValue') ? deletedAtAttribute.defaultValue : null;
8183

82-
deletedAtDefaultValue = deletedAtDefaultValue || { [Op.or]: { [Op.gt]: model.sequelize.literal('CURRENT_TIMESTAMP'), [Op.eq]: null } };
84+
deletedAtDefaultValue = deletedAtDefaultValue || {
85+
[Op.or]: {
86+
[Op.gt]: now,
87+
[Op.eq]: null
88+
}
89+
};
8390

8491
deletedAtObject[deletedAtAttribute.field || deletedAtCol] = deletedAtDefaultValue;
8592

lib/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ exports.sliceArgs = sliceArgs;
391391

392392
function now(dialect) {
393393
const now = new Date();
394-
if (['mysql', 'postgres', 'sqlite'].indexOf(dialect) === -1) {
394+
if (['mysql', 'postgres', 'sqlite', 'mssql'].indexOf(dialect) === -1) {
395395
now.setMilliseconds(0);
396396
}
397397
return now;

test/integration/instance.test.js

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
1616
this.clock = sinon.useFakeTimers();
1717
});
1818

19+
afterEach(function() {
20+
this.clock.reset();
21+
});
22+
1923
after(function() {
2024
this.clock.restore();
2125
});
@@ -51,6 +55,7 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
5155
defaultValue: false
5256
}
5357
});
58+
5459
return this.User.sync({ force: true });
5560
});
5661

@@ -249,18 +254,21 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
249254
const User = this.sequelize.define('IncrementUser', {
250255
aNumber: DataTypes.INTEGER
251256
}, { timestamps: true });
257+
252258
let oldDate;
253259

254-
return User.sync({ force: true }).bind(this).then(() => {
255-
return User.create({aNumber: 1});
256-
}).then(function(user) {
257-
oldDate = user.updatedAt;
260+
return User.sync({ force: true })
261+
.then(() => User.create({ aNumber: 1 }))
262+
.then(user => {
263+
oldDate = user.get('updatedAt');
258264

259-
this.clock.tick(1000);
260-
return user.increment('aNumber', {by: 1});
261-
}).then(() => {
262-
return expect(User.findById(1)).to.eventually.have.property('updatedAt').afterTime(oldDate);
263-
});
265+
this.clock.tick(1000);
266+
return user.increment('aNumber', { by: 1 });
267+
})
268+
.then(user => user.reload())
269+
.then(user => {
270+
return expect(user).to.have.property('updatedAt').afterTime(oldDate);
271+
});
264272
});
265273

266274
it('with timestamps set to true and options.silent set to true', function() {
@@ -1162,11 +1170,20 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
11621170
});
11631171

11641172
it('updates the timestamps', function() {
1165-
const now = new Date(),
1166-
user = this.User.build({ username: 'user' });
1173+
const now = new Date();
1174+
now.setMilliseconds(0);
11671175

1176+
const user = this.User.build({ username: 'user' });
11681177
this.clock.tick(1000);
1169-
return expect(user.save()).to.eventually.have.property('updatedAt').afterTime(now);
1178+
1179+
return user.save().then(savedUser => {
1180+
expect(savedUser).have.property('updatedAt').afterTime(now);
1181+
1182+
this.clock.tick(1000);
1183+
return savedUser.save();
1184+
}).then(updatedUser => {
1185+
expect(updatedUser).have.property('updatedAt').afterTime(now);
1186+
});
11701187
});
11711188

11721189
it('does not update timestamps when passing silent=true', function() {
@@ -1212,15 +1229,6 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
12121229
});
12131230

12141231
describe('when nothing changed', () => {
1215-
1216-
beforeEach(function() {
1217-
this.clock = sinon.useFakeTimers();
1218-
});
1219-
1220-
afterEach(function() {
1221-
this.clock.restore();
1222-
});
1223-
12241232
it('does not update timestamps', function() {
12251233
const self = this;
12261234
return self.User.create({ username: 'John' }).then(() => {

test/integration/instance/update.test.js

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const chai = require('chai'),
55
Sequelize = require('../../../index'),
66
expect = chai.expect,
77
Support = require(__dirname + '/../support'),
8-
dialect = Support.getTestDialect(),
98
DataTypes = require(__dirname + '/../../../lib/data-types'),
109
config = require(__dirname + '/../../config/config'),
1110
current = Support.sequelize;
@@ -140,36 +139,34 @@ describe(Support.getTestDialectTeaser('Instance'), () => {
140139
});
141140
});
142141

143-
if (dialect === 'mysql') {
144-
it('should update timestamps w milliseconds', function() {
145-
const User = this.sequelize.define('User' + config.rand(), {
146-
name: DataTypes.STRING,
147-
bio: DataTypes.TEXT,
148-
email: DataTypes.STRING,
149-
createdAt: {type: DataTypes.DATE(6), allowNull: false},
150-
updatedAt: {type: DataTypes.DATE(6), allowNull: false}
151-
}, {
152-
timestamps: true
153-
});
142+
it('should update timestamps with milliseconds', function() {
143+
const User = this.sequelize.define('User' + config.rand(), {
144+
name: DataTypes.STRING,
145+
bio: DataTypes.TEXT,
146+
email: DataTypes.STRING,
147+
createdAt: {type: DataTypes.DATE(6), allowNull: false},
148+
updatedAt: {type: DataTypes.DATE(6), allowNull: false}
149+
}, {
150+
timestamps: true
151+
});
154152

155-
this.clock.tick(2100); //move the clock forward 2100 ms.
153+
this.clock.tick(2100); //move the clock forward 2100 ms.
156154

157-
return User.sync({force: true}).then(() => {
158-
return User.create({
159-
name: 'snafu',
160-
email: 'email'
161-
}).then(user => {
162-
return user.reload();
163-
}).then(user => {
164-
expect(user.get('name')).to.equal('snafu');
165-
expect(user.get('email')).to.equal('email');
166-
const testDate = new Date();
167-
testDate.setTime(2100);
168-
expect(user.get('createdAt')).to.equalTime(testDate);
169-
});
155+
return User.sync({force: true}).then(() => {
156+
return User.create({
157+
name: 'snafu',
158+
email: 'email'
159+
}).then(user => {
160+
return user.reload();
161+
}).then(user => {
162+
expect(user.get('name')).to.equal('snafu');
163+
expect(user.get('email')).to.equal('email');
164+
const testDate = new Date();
165+
testDate.setTime(2100);
166+
expect(user.get('createdAt')).to.equalTime(testDate);
170167
});
171168
});
172-
}
169+
});
173170

174171
it('should only save passed attributes', function() {
175172
const user = this.User.build();

0 commit comments

Comments
 (0)