-
-
Notifications
You must be signed in to change notification settings - Fork 364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update batchPut to work with timestamps #449
Conversation
Pull Request Test Coverage Report for Build 685
💛 - Coveralls |
1 similar comment
Pull Request Test Coverage Report for Build 685
💛 - Coveralls |
Pull Request Test Coverage Report for Build 689
💛 - Coveralls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really good. Just a few suggestions.
docs/_docs/model.md
Outdated
|
||
**updateTimestamps**: boolean | ||
|
||
Should update the `updatedAt` timestamp if exists. Defaults to true. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be Defaults to false
for the documentation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's right. Oops!
lib/Model.js
Outdated
if (options.updateTimestamps === true) { | ||
toDynamoOptions.updateTimestamps = true; | ||
} | ||
if (options.updateExpires === true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of doing these two if statements why not do something like the following?
let toDynamoOptions = {
updateTimestamps: options.updateTimestamps || false,
updateExpires: options.updateExpires || false
};
We might even be able to reduce it to something like the following since it'd be falsey if it doesn't exist.
let toDynamoOptions = {
updateTimestamps: options.updateTimestamps,
updateExpires: options.updateExpires
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I personally like this more (your first version). I was trying to copy the existing code style as much as possible. But since you suggested it yourself, I'll definitely change it. Not a fan of the second version, because it's slightly less telling and not as safe. So I'll go with the first one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dolsem I'd like to refactor a lot of that code and fix up a lot of things to use more things like the versions I had above. It'd be a massive project but at some point I'd like to go through and clean up a lot of the Dynamoose code to make it more clean.
Not sure when that will happen tho. Until then I fully support new code using those type of clean coding practices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, got you.
test/Model.js
Outdated
should.exist(result3); | ||
result3.length.should.eql(cats.length); | ||
|
||
result3.forEach(cat => cat.myLittleUpdatedAt.should.not.eql(timestamps[cat.id])); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm thinking we should set this to check to ensure the new updated at is greater than the old value. Just to make this test more thorough.
test/Model.js
Outdated
|
||
result3.forEach((cat) => { | ||
cat.array.length.should.eql(2); | ||
cat.expires.should.not.eql(originalExpires[cat.id]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing here, this should probably check to see if it's greater than the old value.
test/Model.js
Outdated
var timestamps = {}; | ||
for (var i=0 ; i<10 ; ++i) { | ||
cats[i].name = 'John_'+i; | ||
Object.assign(timestamps, { [cats[i].id]: new Date(cats[i].myLittleUpdatedAt) }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a huge fan of Object.assign
if we can avoid it. Is there a better method for this? Something like the following maybe?
timestamps[cats[i].id] = new Date(cats[i].myLittleUpdatedAt);
To me that is much simpler code and easier to understand. I don't think Object.assign
makes a lot of sense in this context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
test/Model.js
Outdated
var timestamps = {}; | ||
for (var i=0 ; i<10 ; ++i) { | ||
cats[i].name = 'John_'+i; | ||
Object.assign(timestamps, { [cats[i].id]: new Date(cats[i].myLittleUpdatedAt) }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing here. Something like the following maybe?
timestamps[cats[i].id] = new Date(cats[i].myLittleUpdatedAt);
test/Model.js
Outdated
var timestamps = {}; | ||
for (var i=0 ; i<10 ; ++i) { | ||
cats[i].name = 'John_'+i; | ||
Object.assign(timestamps, { [cats[i].id]: new Date(cats[i].myLittleUpdatedAt) }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing here. Something like the following maybe?
timestamps[cats[i].id] = new Date(cats[i].myLittleUpdatedAt);
test/Model.js
Outdated
result3.length.should.eql(cats.length); | ||
|
||
originalExpires = result3.reduce( | ||
(acc, cat) => Object.assign(acc, { [cat.id]: cat.expires }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Object.assign
makes sense to me here. Here is another option, but totally up to you if you want to use this or not. I think your code is completely fine here, but just another option to keep it consistent in terms of not using Object.assign
.
Change the code above to:
var originalExpires = {};
Then here do:
result3.forEach(cat => {
acc[cat.id] = cat.expires;
});
You could also make that a for loop since it seems like you are using that a lot throughout these tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think it's always best to stick to either good old procedural style or functional, not combining the two. I lean towards functional with JavaScript, but I was reusing some of the code from other tests in the same file, I didn't want my tests to look radically different from everything around. I guess I'll make things more consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dolsem If Object.assign
is used a lot throughout the tests then that is fine. I'm not sure what is currently being used for these cases.
21498d7
to
03b1f44
Compare
03b1f44
to
6c359e7
Compare
I've just made the updates you requested, as well as a few other updates to code style. Let me know if there's anything else. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more thing
timestamps[id] = new Date(myLittleUpdatedAt); | ||
}); | ||
|
||
await new Promise(resolve => setTimeout(resolve, 1000)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized one more thing I forgot to mention. Why not make this something much shorter? Like 5 or even 1? Is there a specific reason why we have to wait a full second here? Waiting just a few milliseconds should ensure that the timestamps are later than the original value, correct?
If we decide to edit it we have to make sure we do it throughout these new tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I tried making it shorter, and the tests would sometimes fail. Seems like when timestamps get updated milliseconds get stripped away either on the original objects after they saved or on the results of batchGet, not sure which one right now. I didn't have time to investigate this, so I don't know if this is the result of floor, ceiling, or round, so to be safe I made it wait a full second. This made the tests deterministic, no chance of failure anymore. I might be mistaken, but I think the same timeout is used for other tests around timestamps in the test suit too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@dolsem Thanks for your hard work on this! I'll get this merged in soon!! |
Summary:
Second take on #447.
Currently
batchPut
fails with errorCannot read property 'updateTimestamps' of undefined
if a model uses timestamps. The error results from this line, becausetoDynamo
is called without options here.This PR fixes the issue and adds two options to
batchPut
:updateTimestamps
(defaults tofalse
, because currentlybatchPut
does not update timestamps), andupdateExpires
(also defaults tofalse
).Type (select 1):
Is this a breaking change? (select 1):
Is this ready to be merged into Dynamoose? (select 1):
Are all the tests currently passing on this PR? (select 1):
Other:
npm test
from the root of the project directory to ensure all tests continue to pass